home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 101 / CD-ROM 101.iso / compl / maya5ple / Install_MayaPLE5_English.exe / Maya / Data1.cab / includeSurfaceFlowGlobals.me < prev    next >
Encoding:
Text File  |  2003-07-17  |  91.1 KB  |  2,829 lines

  1. // Copyright (C) 1997-2002 Alias|Wavefront,
  2. // a division of Silicon Graphics Limited.
  3. //
  4. // The information in this file is provided for the exclusive use of the
  5. // licensees of Alias|Wavefront.  Such users have the right to use, modify,
  6. // and incorporate this code into other products for purposes authorized
  7. // by the Alias|Wavefront license agreement, without fee.
  8. //
  9. // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  10. // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  11. // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  12. // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  13. // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  14. // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. // PERFORMANCE OF THIS SOFTWARE.
  16. //
  17. includeEffectsGlobals();
  18.  
  19. global proc includeSurfaceFlowGlobals()
  20. //
  21. // Description:
  22. //
  23. //     This is the procedure that users will need to call once
  24. // to enable the surface flow scripts to be used from the
  25. // command line or from their scripts.  The UI does this
  26. // automatically, so this is not needed if just using the
  27. // menus.
  28. //
  29. {
  30. }
  31.  
  32. proc string surfaceFlowTag( string $object )
  33. //
  34. // Description:
  35. //
  36. //    Each surface flow object in a scene has a unique tag associated with
  37. // it.  This is used when editing the particle objects' expressions.  This
  38. // procedure returns the tag for the given surface flow object.
  39. //
  40. {
  41.     if( isSurfaceFlow( $object ) == 0 )
  42.     {
  43.         return "";
  44.     }
  45.  
  46.     string $tag = `getAttr ($object+".surfaceFlowTag")`;
  47.     return $tag;
  48. }
  49.  
  50. proc string getUniqueSurfaceFlowTag()
  51. //
  52. // Description:
  53. //
  54. //    Each surface flow object in a scene has a unique tag associated with
  55. // it.  This is used when editing the particle objects' expressions.  When
  56. // creating a new surface flow object, this procedure will return a unique
  57. // tag for that surface flow object to use.
  58. //
  59. {
  60.     string $allNodes[] = `ls`;
  61.     string $surfaceFlowTags[];
  62.     clear( $surfaceFlowTags );
  63.  
  64.     int $i;
  65.     for( $i = 0; $i < size( $allNodes ); $i ++ )
  66.     {
  67.         if( isSurfaceFlow( $allNodes[$i] ) == 1 )
  68.         {
  69.             string $tag = surfaceFlowTag( $allNodes[$i] );
  70.             $surfaceFlowTags = appendSingleToStringArray( $surfaceFlowTags, surfaceFlowTag($allNodes[$i]) );
  71.         }
  72.     }
  73.  
  74.     string $result = "";
  75.  
  76.     int $currentValue = 0;
  77.     int $done = 0;
  78.     while( $done == 0 )
  79.     {
  80.         string $testString = ("_SF_TAG_"+$currentValue);
  81.         if( findInStringArray( $testString, $surfaceFlowTags ) == -1 )
  82.         {
  83.             $result = $testString;
  84.             $done = 1;
  85.         }
  86.         $currentValue ++;
  87.     }
  88.  
  89.     return $result;
  90. }
  91.  
  92. /////////////////////////////////////////////////////////////////////////////////
  93.  
  94. proc string[] surfaceFlowEffectAttrConnections( string $object, string $particle )
  95. //
  96. // Returns string array.
  97. //
  98. //    The first element is the actual attribute name on the particle object that
  99. //    holds the effectStrength values for the given surface flow group.  This is only
  100. //    the attribute name without the particle object's name.  This makes it easier to
  101. //    give the deleteAtr command.
  102. //
  103. //    The remaining elements are disconnectAttr pairs that should be broken (in the order
  104. //    given) before the deleteAttr can be called for the attribute.
  105. //
  106. {
  107.     string $result[];
  108.     clear( $result );
  109.  
  110.     if( isSurfaceFlow( $object ) == 0 )
  111.     {
  112.         error("The object, \""+$object+"\", is not a surface flow object.");
  113.     }
  114.  
  115.     string $particleShape[] = `ls -o -dag -s -type particle $particle`;
  116.     if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 )
  117.     {
  118.         //
  119.         // First put the attribute name in the result string.
  120.         //
  121.         string $effectStrengthAttr[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".effectStrengthAttribute")`;
  122.         int $index = findInStringArray( $particleShape[0], $effectStrengthAttr );
  123.         if( $index == -1 )
  124.         {
  125.             return $result;
  126.         }
  127.         $effectStrengthAttr = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".effectStrengthAttribute")`;
  128.         $actualAttr = $effectStrengthAttr[$index*2+1];
  129.  
  130.         string $tokens[];
  131.         clear( $tokens );
  132.         tokenize( $actualAttr, ".", $tokens );
  133.         $result[0] = $tokens[1];
  134.         string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`;
  135.         string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`;
  136.         int $j;
  137.         for( $j = 0; $j < size($inputsToActualAttr); $j ++ )
  138.         {
  139.             $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] );
  140.             $result = appendSingleToStringArray( $result, $actualAttr );
  141.         }
  142.         for( $j = 0; $j < size($outputsFromActualAttr); $j ++ )
  143.         {
  144.             $result = appendSingleToStringArray( $result, $actualAttr );
  145.             $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] );
  146.         }
  147.     }
  148.  
  149.     return $result;
  150. }
  151.  
  152. proc string[] surfaceFlowEffectStrengthObjects( string $object, string $particle )
  153. //
  154. // Returns an array off all of the manipPosition attributes on $particle, that represent $object.
  155. // These connections can 
  156. {
  157.     string $result[];
  158.     clear( $result );
  159.  
  160.     if( isSurfaceFlow( $object ) == 0 )
  161.     {
  162.         error("The object, \""+$object+"\", is not a surface flow object.");
  163.     }
  164.  
  165.     string $particleShape[] = `ls -o -dag -s -type particle $particle`;
  166.     if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 )
  167.     {
  168.         string $flowingParticles[] = surfaceFlowParticles( $object );
  169.         int $index = findInStringArray( $particleShape[0], $flowingParticles );
  170.         if( $index == -1 )
  171.         {
  172.             return $result;
  173.         }
  174.  
  175.         //
  176.         // Now put the ramp name in the result string.
  177.         //
  178.         string $effectStrengthRamp[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".effectStrengthRamp")`;
  179.         $result[0] = $effectStrengthRamp[$index];
  180.  
  181.         //
  182.         // Now put the array mapper name in the result string.
  183.         //
  184.         string $effectStrengthMapper[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".effectStrengthArrayMapper")`;
  185.         $result[1] = $effectStrengthMapper[$index];
  186.     }
  187.  
  188.     return $result;
  189. }
  190.  
  191. proc string[] surfaceFlowManipArrayMappers( string $object, string $particle )
  192. //
  193. // Returns an array off all of the manipPosition attributes on $particle, that represent $object.
  194. // These connections can 
  195. {
  196.     string $result[];
  197.     clear( $result );
  198.  
  199.     if( isSurfaceFlow( $object ) == 0 )
  200.     {
  201.         error("The object, \""+$object+"\", is not a surface flow object.");
  202.     }
  203.  
  204.     string $particleShape[] = `ls -o -dag -s -type particle $particle`;
  205.     if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 )
  206.     {
  207.         string $arrayMappers[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".manipPositionArrayMapper")`;
  208.         int $i;
  209.         for( $i = 0; $i < size($arrayMappers); $i ++ )
  210.         {
  211.             string $inputs[] = `listConnections -source true -destination false -shapes true -plugs false ($arrayMappers[$i]+".vCoordPP")`;
  212.             if( $inputs[0] == $particleShape[0] )
  213.             {
  214.                 $result = appendSingleToStringArray( $result, $arrayMappers[$i] );
  215.             }
  216.         }
  217.     }
  218.  
  219.     return $result;
  220. }
  221.  
  222. proc string[] surfaceFlowManipPositionAttributes( string $object, string $particle )
  223. //
  224. // Returns an array off all of the manipPosition attributes on $particle, that represent $object.
  225. // These connections can 
  226. {
  227.     string $result[];
  228.     clear( $result );
  229.  
  230.     if( isSurfaceFlow( $object ) == 0 )
  231.     {
  232.         error("The object, \""+$object+"\", is not a surface flow object.");
  233.     }
  234.  
  235.     string $particleShape[] = `ls -o -dag -s -type particle $particle`;
  236.     if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 )
  237.     {
  238.         string $manipPositionAttrNodes[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".manipPositionAttribute")`;
  239.         int $index = findInStringArray( $particleShape[0], $manipPositionAttrNodes );
  240.         if( $index == -1 )
  241.         {
  242.             $result[0] = "0";
  243.             return $result;
  244.         }
  245.         string $manipPositionAttrPlugs[] = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".manipPositionAttribute")`;
  246.         int $manipAttrCount = 0;
  247.         int $i;
  248.         for( $i = 0; $i < size( $manipPositionAttrNodes ); $i ++ )
  249.         {
  250.             if( $manipPositionAttrNodes[$i] == $particleShape[0] )
  251.             {
  252.                 $manipAttrCount ++;
  253.             }
  254.         }
  255.         $result[0] = $manipAttrCount;
  256.  
  257.         for( $i = 0; $i < size( $manipPositionAttrNodes ); $i ++ )
  258.         {
  259.             if( $manipPositionAttrNodes[$i] == $particleShape[0] )
  260.             {
  261.                 string $actualAttr = $manipPositionAttrPlugs[$i*2+1];
  262.                 string $tokens[];
  263.                 clear( $tokens );
  264.                 tokenize( $actualAttr, ".", $tokens );
  265.                 $result = appendSingleToStringArray( $result, $tokens[1] );
  266.             }
  267.         }
  268.  
  269.         for( $i = 0; $i < size( $manipPositionAttrNodes ); $i ++ )
  270.         {
  271.             if( $manipPositionAttrNodes[$i] == $particleShape[0] )
  272.             {
  273.                 string $actualAttr = $manipPositionAttrPlugs[$i*2+1];
  274.                 string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`;
  275.                 string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`;
  276.                 int $j;
  277.                 for( $j = 0; $j < size($inputsToActualAttr); $j ++ )
  278.                 {
  279.                     $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] );
  280.                     $result = appendSingleToStringArray( $result, $actualAttr );
  281.                 }
  282.                 for( $j = 0; $j < size($outputsFromActualAttr); $j ++ )
  283.                 {
  284.                     $result = appendSingleToStringArray( $result, $actualAttr );
  285.                     $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] );
  286.                 }
  287.             }
  288.         }
  289.     }
  290.  
  291.     return $result;
  292. }
  293.  
  294. proc string[] surfaceFlowGoalWeightAttribute( string $object, string $particle )
  295. //
  296. // Returns string array.
  297. //
  298. //    The first element is the actual attribute name on the particle object that
  299. //    holds the effectStrength values for the given surface flow group.  This is only
  300. //    the attribute name without the particle object's name.  This makes it easier to
  301. //    give the deleteAtr command.
  302. //
  303. //    The remaining elements are disconnectAttr pairs that should be broken (in the order
  304. //    given) before the deleteAttr can be called for the attribute.
  305. //
  306. {
  307.     string $result[];
  308.     clear( $result );
  309.  
  310.     if( isSurfaceFlow( $object ) == 0 )
  311.     {
  312.         error("The object, \""+$object+"\", is not a surface flow object.");
  313.     }
  314.  
  315.     string $particleShape[] = `ls -o -dag -s -type particle $particle`;
  316.     if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 )
  317.     {
  318.         //
  319.         // First put the attribute name in the result string.
  320.         //
  321.         string $goalWeightAttr[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".goalWeightAttribute")`;
  322.         int $index = findInStringArray( $particleShape[0], $goalWeightAttr );
  323.         if( $index == -1 )
  324.         {
  325.             return $result;
  326.         }
  327.         $goalWeightAttr = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".goalWeightAttribute")`;
  328.         $actualAttr = $goalWeightAttr[$index*2+1];
  329.  
  330.         string $tokens[];
  331.         clear( $tokens );
  332.         tokenize( $actualAttr, ".", $tokens );
  333.         tokenize( $tokens[1], "[", $tokens );
  334.         tokenize( $tokens[1], "]", $tokens );
  335.         $result[0] = $tokens[0];
  336.         string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`;
  337.         string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`;
  338.         int $j;
  339.         for( $j = 0; $j < size($inputsToActualAttr); $j ++ )
  340.         {
  341.             $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] );
  342.             $result = appendSingleToStringArray( $result, $actualAttr );
  343.         }
  344.         for( $j = 0; $j < size($outputsFromActualAttr); $j ++ )
  345.         {
  346.             $result = appendSingleToStringArray( $result, $actualAttr );
  347.             $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] );
  348.         }
  349.     }
  350.  
  351.     return $result;
  352. }
  353.  
  354. proc string[] surfaceFlowAdjustedAgeNormalizedAttribute( string $object, string $particle )
  355. //
  356. // Returns string array.
  357. //
  358. //    The first element is the actual attribute name on the particle object that
  359. //    holds the effectStrength values for the given surface flow group.  This is only
  360. //    the attribute name without the particle object's name.  This makes it easier to
  361. //    give the deleteAtr command.
  362. //
  363. //    The remaining elements are disconnectAttr pairs that should be broken (in the order
  364. //    given) before the deleteAttr can be called for the attribute.
  365. //
  366. {
  367.     string $result[];
  368.     clear( $result );
  369.  
  370.     if( isSurfaceFlow( $object ) == 0 )
  371.     {
  372.         error("The object, \""+$object+"\", is not a surface flow object.");
  373.     }
  374.  
  375.     string $particleShape[] = `ls -o -dag -s -type particle $particle`;
  376.     if( isParticleInSurfaceFlow($object, $particleShape[0]) == 1 )
  377.     {
  378.         //
  379.         // First put the attribute name in the result string.
  380.         //
  381.         string $adjustedAgeNormalizedAttr[] = `listConnections -source true -destination false -shapes true -plugs 0 ($object+".adjustedAgeNormalizedAttribute")`;
  382.         int $index = findInStringArray( $particleShape[0], $adjustedAgeNormalizedAttr );
  383.         if( $index == -1 )
  384.         {
  385.             return $result;
  386.         }
  387.         $adjustedAgeNormalizedAttr = `listConnections -source true -destination false -shapes true -plugs 1 -connections 1 ($object+".adjustedAgeNormalizedAttribute")`;
  388.         $actualAttr = $adjustedAgeNormalizedAttr[$index*2+1];
  389.  
  390.         string $tokens[];
  391.         clear( $tokens );
  392.         tokenize( $actualAttr, ".", $tokens );
  393.         $result[0] = $tokens[1];
  394.         string $outputsFromActualAttr[] = `listConnections -source false -destination true -plugs 1 -shapes 1 $actualAttr`;
  395.         string $inputsToActualAttr[] = `listConnections -source true -destination false -plugs 1 -shapes 1 $actualAttr`;
  396.         int $j;
  397.         for( $j = 0; $j < size($inputsToActualAttr); $j ++ )
  398.         {
  399.             $result = appendSingleToStringArray( $result, $inputsToActualAttr[$j] );
  400.             $result = appendSingleToStringArray( $result, $actualAttr );
  401.         }
  402.         for( $j = 0; $j < size($outputsFromActualAttr); $j ++ )
  403.         {
  404.             $result = appendSingleToStringArray( $result, $actualAttr );
  405.             $result = appendSingleToStringArray( $result, $outputsFromActualAttr[$j] );
  406.         }
  407.     }
  408.  
  409.     return $result;
  410. }
  411.  
  412. ////////////////////////////////////////////////////////////////////////////
  413.  
  414. proc string[] surfaceFlowMainManips( string $object )
  415. {
  416.     string $result[];
  417.     clear( $result );
  418.  
  419.     if( isSurfaceFlow( $object ) == 0 )
  420.     {
  421.         error("The object, \""+$object+"\", is not a surface flow object.");
  422.     }
  423.  
  424.     $result = getMarkedObjects( $object, "surfaceFlowMainManips" );
  425.     return $result;
  426. }
  427.  
  428. proc string[] surfaceFlowSubManips( string $object )
  429. {
  430.     string $result[];
  431.     clear( $result );
  432.  
  433.     if( isSurfaceFlow( $object ) == 0 )
  434.     {
  435.         error("The object, \""+$object+"\", is not a surface flow object.");
  436.     }
  437.  
  438.     $result = getMarkedObjects( $object, "surfaceFlowSubManips" );
  439.     return $result;
  440. }
  441.  
  442. proc string[] surfaceFlowMainRamps( string $object )
  443. {
  444.     string $result[];
  445.     clear( $result );
  446.  
  447.     if( isSurfaceFlow( $object ) == 0 )
  448.     {
  449.         error("The object, \""+$object+"\", is not a surface flow object.");
  450.     }
  451.  
  452.     $result = getMarkedObjects( $object, "surfaceFlowMainRamps" );
  453.     return $result;
  454. }
  455.  
  456. proc string[] surfaceFlowSubRamps( string $object )
  457. {
  458.     string $result[];
  459.     clear( $result );
  460.  
  461.     if( isSurfaceFlow( $object ) == 0 )
  462.     {
  463.         error("The object, \""+$object+"\", is not a surface flow object.");
  464.     }
  465.  
  466.     $result = getMarkedObjects( $object, "surfaceFlowSubRamps" );
  467.     return $result;
  468. }
  469.  
  470. proc string[] surfaceFlowMainLofts( string $object )
  471. {
  472.     string $result[];
  473.     clear( $result );
  474.  
  475.     if( isSurfaceFlow( $object ) == 0 )
  476.     {
  477.         error("The object, \""+$object+"\", is not a surface flow object.");
  478.     }
  479.  
  480.     $result = getMarkedObjects( $object, "surfaceFlowMainLofts" );
  481.     return $result;
  482. }
  483.  
  484. proc string[] surfaceFlowSubLofts( string $object )
  485. {
  486.     string $result[];
  487.     clear( $result );
  488.  
  489.     if( isSurfaceFlow( $object ) == 0 )
  490.     {
  491.         error("The object, \""+$object+"\", is not a surface flow object.");
  492.     }
  493.  
  494.     $result = getMarkedObjects( $object, "surfaceFlowSubLofts" );
  495.     return $result;
  496. }
  497.  
  498. proc string[] surfaceFlowMainResolutionPlanes( string $object )
  499. {
  500.     string $result[];
  501.     clear( $result );
  502.  
  503.     if( isSurfaceFlow( $object ) == 0 )
  504.     {
  505.         error("The object, \""+$object+"\", is not a surface flow object.");
  506.     }
  507.  
  508.     $result = getMarkedObjects( $object, "surfaceFlowMainResolutionPlanes" );
  509.     return $result;
  510. }
  511.  
  512. proc string[] surfaceFlowSubResolutionPlanes( string $object )
  513. {
  514.     string $result[];
  515.     clear( $result );
  516.  
  517.     if( isSurfaceFlow( $object ) == 0 )
  518.     {
  519.         error("The object, \""+$object+"\", is not a surface flow object.");
  520.     }
  521.  
  522.     $result = getMarkedObjects( $object, "surfaceFlowSubResolutionPlanes" );
  523.     return $result;
  524. }
  525.  
  526. proc string[] surfaceFlowMainEdgeCurves( string $object )
  527. {
  528.     string $result[];
  529.     clear( $result );
  530.  
  531.     if( isSurfaceFlow( $object ) == 0 )
  532.     {
  533.         error("The object, \""+$object+"\", is not a surface flow object.");
  534.     }
  535.  
  536.     $result = getMarkedObjects( $object, "surfaceFlowMainEdgeCurves" );
  537.     return $result;
  538. }
  539.  
  540. proc string[] surfaceFlowSubEdgeCurves( string $object )
  541. {
  542.     string $result[];
  543.     clear( $result );
  544.  
  545.     if( isSurfaceFlow( $object ) == 0 )
  546.     {
  547.         error("The object, \""+$object+"\", is not a surface flow object.");
  548.     }
  549.  
  550.     $result = getMarkedObjects( $object, "surfaceFlowSubEdgeCurves" );
  551.     return $result;
  552. }
  553.  
  554. proc string[] surfaceFlowMainMinCurves( string $object )
  555. {
  556.     string $result[];
  557.     clear( $result );
  558.  
  559.     if( isSurfaceFlow( $object ) == 0 )
  560.     {
  561.         error("The object, \""+$object+"\", is not a surface flow object.");
  562.     }
  563.  
  564.     $result = getMarkedObjects( $object, "surfaceFlowMainMinCurves" );
  565.     return $result;
  566. }
  567.  
  568. proc string[] surfaceFlowSubMinCurves( string $object )
  569. {
  570.     string $result[];
  571.     clear( $result );
  572.  
  573.     if( isSurfaceFlow( $object ) == 0 )
  574.     {
  575.         error("The object, \""+$object+"\", is not a surface flow object.");
  576.     }
  577.  
  578.     $result = getMarkedObjects( $object, "surfaceFlowSubMinCurves" );
  579.     return $result;
  580. }
  581.  
  582. proc string[] surfaceFlowMainMaxCurves( string $object )
  583. {
  584.     string $result[];
  585.     clear( $result );
  586.  
  587.     if( isSurfaceFlow( $object ) == 0 )
  588.     {
  589.         error("The object, \""+$object+"\", is not a surface flow object.");
  590.     }
  591.  
  592.     $result = getMarkedObjects( $object, "surfaceFlowMainMaxCurves" );
  593.     return $result;
  594. }
  595.  
  596. proc string[] surfaceFlowSubMaxCurves( string $object )
  597. {
  598.     string $result[];
  599.     clear( $result );
  600.  
  601.     if( isSurfaceFlow( $object ) == 0 )
  602.     {
  603.         error("The object, \""+$object+"\", is not a surface flow object.");
  604.     }
  605.  
  606.     $result = getMarkedObjects( $object, "surfaceFlowSubMaxCurves" );
  607.     return $result;
  608. }
  609.  
  610. /////////////////////////////////////////////////////////////////////////////////////
  611.  
  612. proc string[] surfaceFlowNodesToDelete( string $object )
  613. {
  614.     string $result[];
  615.     clear( $result );
  616.  
  617.     if( isSurfaceFlow( $object ) == 0 )
  618.     {
  619.         return $result;
  620.     }
  621.  
  622.     $result = getMarkedObjects( $object, "nodesToDelete" );
  623.  
  624.     return $result;
  625. }
  626.  
  627. proc markNodesNonHistoricallyInteresting( string $object )
  628. {
  629.     if( isSurfaceFlow( $object ) == 0 )
  630.     {
  631.         return;
  632.     }
  633.  
  634.     string $allNodes[] = surfaceFlowNodesToDelete( $object );
  635.     int $i;
  636.     for( $i = 0; $i < size($allNodes); $i ++ )
  637.     {
  638.         string $thisObject = $allNodes[$i];
  639.         if( ( findInStringArray( $thisObject, surfaceFlowParticles( $object ) ) == -1 ) &&
  640.             ( $thisObject != surfaceFlowEmitter( $object ) ) )
  641.         {
  642.             setAttr ($thisObject+".isHistoricallyInteresting") 0;
  643.         }
  644.     }
  645. }
  646.  
  647. proc int cleanupSurfaceFlowAttributes( string $flow )
  648. {
  649.     if( isSurfaceFlow( $flow ) == 0 )
  650.     {
  651.         return 0;
  652.     }
  653.  
  654.     string $scalarAttrs[] = `listAttr -scalar -keyable $flow`;
  655.     int $i;
  656.     for( $i = 0; $i < size( $scalarAttrs ); $i ++ )
  657.     {
  658.         if( ( gmatch( $scalarAttrs[$i], "minAgeRatio_*" ) == 1 ) ||
  659.             ( gmatch( $scalarAttrs[$i], "maxAgeRatio_*" ) == 1 ) ||
  660.             ( gmatch( $scalarAttrs[$i], "goalWeight_*" ) == 1 ) )
  661.         {
  662.             string $outputs[] = `listConnections -source false -destination true ($flow+"."+$scalarAttrs[$i])`;
  663.             if( size( $outputs ) == 0 )
  664.             {
  665.                 deleteAttr -at $scalarAttrs[$i] $flow;
  666.             }
  667.         }
  668.     }
  669.  
  670.     return 1;
  671. }
  672.  
  673. //////////////////////////////////////////////////////////////////////////
  674.  
  675. proc markNewNonDagNodes( string $flowGroup, string $oldNodes[], string $newNodes[] )
  676. {
  677.     string $nodesToMark[];
  678.     clear( $nodesToMark );
  679.  
  680.     if( isSurfaceFlow( $flowGroup ) == 0 )
  681.     {
  682.         return;
  683.     }
  684.  
  685.     string $oldNodesToDelete[] = surfaceFlowNodesToDelete( $flowGroup );
  686.  
  687.     int $i;
  688.     for( $i = 0; $i < size( $newNodes ); $i ++ )
  689.     {
  690.         //
  691.         // If this object is not in the $oldNodes array, then it was
  692.         // created during the execution of this script.
  693.         //
  694.         if( findInStringArray( $newNodes[$i], $oldNodes ) == -1 )
  695.         {
  696.             //
  697.             // We only want to mark non-DAG nodes for deletion in this way,
  698.             // since all of the DAG objects created (except for the particles)
  699.             // are under the main group node in the DAG and can be deleted
  700.             // by deleting the main group.
  701.             //
  702.             string $dagNodes[] = `ls -type transform -type shape $newNodes[$i]`;
  703.             if( size( $dagNodes ) == 0 )
  704.             {
  705.                 //
  706.                 // Only mark it if it is not already in the list of nodes to
  707.                 // delete for this surface flow group.  This should never
  708.                 // happen, but just in case...
  709.                 //
  710.                 if( findInStringArray( $newNodes[$i], $oldNodesToDelete ) == -1 )
  711.                 {
  712.                     markObjectWithAttribute( $newNodes[$i], $flowGroup, "nodesToDelete" );
  713.                 }
  714.             }
  715.         }
  716.     }
  717. }
  718.  
  719. proc string makeSurfaceFlowGroup(
  720.     string $surface,
  721.     string $name,
  722.     string $type,
  723.     int $controlResolution,
  724.     int $subControlResolution,
  725.     int $manipResolution,
  726.     float $goalWeight,
  727.     float $emitterRate,
  728.     float $minAgeRatio,
  729.     float $maxAgeRatio )
  730. {
  731.     $controlResolution = max(2,$controlResolution);
  732.     $subControlResolution = max(0,$subControlResolution);
  733.     $manipResolution = max( 3, $manipResolution );
  734.     $goalWeight = max( 0, min( 1, $goalWeight ) );
  735.     $emitterRate = max( 0, $emitterRate );
  736.     $minAgeRatio = max( 0, min( 1, $minAgeRatio ) );
  737.     $maxAgeRatio = max( 0, min( 1, $maxAgeRatio ) );
  738.  
  739.     //
  740.     // Check to see if the given surface is really a surface,
  741.     // and get the shape from it.
  742.     //
  743.     string $surfaceShape = "";
  744.     if( `objExists $surface` == 0 )
  745.     {
  746.         error("Object, \""+$surface+"\", does not exists.  Can not create a surface flow group.");
  747.     }
  748.  
  749.     string $surfaceShapes[] = `ls -dag -type nurbsSurface $surface`;
  750.     if( size( $surfaceShapes ) == 0 )
  751.     {
  752.         //
  753.         // No nurbsSurface shapes that can be found from the given name.
  754.         //
  755.         error("No nurbsSurface shape or transform matches the name, \""+$surface+"\".  Can not create a surface flow group.");
  756.     }
  757.     else if( size( $surfaceShapes ) > 1 )
  758.     {
  759.         //
  760.         // Too many nurbsSurface shapes match the given name.  Tell the
  761.         // user to be more specific.
  762.         // 
  763.         error("More than one nurbsSurface shape found using the name, \""+$surface+"\".  Can not create a surface flow group.");
  764.     }
  765.     else
  766.     {
  767.         $surfaceShape = $surfaceShapes[0];
  768.     }
  769.  
  770.     //
  771.     // These were changd to always use [0-1] because now the
  772.     // "superDuplicated" surface is rebuilt to always be between
  773.     // [0-1].  That allows the effect to respond to any changes made
  774.     // to the original surface that might alter the way that it is
  775.     // parameterized.
  776.     //
  777.     float $surfaceMinU = 0; // `getAttr ($surfaceShape+".minValueU")`;
  778.     float $surfaceMaxU = 1; // `getAttr ($surfaceShape+".maxValueU")`;
  779.  
  780.     float $surfaceMinV = 0; // `getAttr ($surfaceShape+".minValueV")`;
  781.     float $surfaceMaxV = 1; // `getAttr ($surfaceShape+".maxValueV")`;
  782.  
  783.     group -empty;
  784.     if( $name == "" )
  785.     {
  786.         rename "SurfaceFlow#";
  787.     }
  788.     else
  789.     {
  790.         rename $name;
  791.     }
  792.     string $flowGroup = getSelectedObject( 0 );
  793.     //
  794.     // First, lock and hide all of the transformation attributes
  795.     // for the surface flow group.  This object is not intended
  796.     // to be transformed.
  797.     //
  798.     lockTransformations( $flowGroup );
  799.  
  800.     superDuplicateSurface( $surfaceShape );
  801.     string $newSurface = getSelectedObject( 0 );
  802.     //
  803.     // We rebuild our copy of the surface to guarantee the parameterization
  804.     // of the surface that we use.  This allows the user to do literally anything
  805.     // to the original surface, while the surface flow maintains a consistent
  806.     // parameterization to work with.
  807.     //
  808.     rebuildSurface -ch 1 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 1 -kc 0 -su 4 -du 3 -sv 4 -dv 3 -tol 0.01  -dir 2 $newSurface;
  809.     setAttr ($newSurface+".template") 1;
  810.     hide $newSurface;
  811.     markObjectWithAttribute($surfaceShape,$flowGroup,"referenceFlowSurface");
  812.     markObjectWithAttribute($newSurface,$flowGroup,"actualFlowSurface");
  813.  
  814.     float $minValue, $maxValue, $range;
  815.     if( $type == "u" )
  816.     {
  817.         $minValue = $surfaceMinU;
  818.         $maxValue = $surfaceMaxU;
  819.         $range = $surfaceMaxU - $surfaceMinU;
  820.     }
  821.     else if( ($type == "-u") || ( `about -mac` && ($type == "minusU") ) ) // Fix for 156627
  822.     {
  823.         $minValue = $surfaceMaxU;
  824.         $maxValue = $surfaceMinU;
  825.         $range = $surfaceMinU - $surfaceMaxU;
  826.         $type = "u";
  827.     }
  828.     else if( $type == "v" )
  829.     {
  830.         $minValue = $surfaceMinV;
  831.         $maxValue = $surfaceMaxV;
  832.         $range = $surfaceMaxV - $surfaceMinV;
  833.     }
  834.     else if( ($type == "-v") || ( `about -mac` && ($type == "minusV") ) )
  835.     {
  836.         $minValue = $surfaceMaxV;
  837.         $maxValue = $surfaceMinV;
  838.         $range = $surfaceMinV - $surfaceMaxV;
  839.         $type = "v";
  840.     }
  841.     else
  842.     {
  843.         error("Unknown surface flow type, \""+$type+"\".  Can not create surfaceFlow Group.");
  844.     }
  845.  
  846.     string $mainManips[];
  847.     clear( $mainManips );
  848.  
  849.     string $subManips[];
  850.     clear( $subManips );
  851.  
  852.     string $ramps[];
  853.     clear( $ramps );
  854.  
  855.     string $lofts[];
  856.     clear( $lofts );
  857.  
  858.     string $edgeCurves[];
  859.     clear( $edgeCurves );
  860.  
  861.     string $minCurves[];
  862.     clear( $minCurves );
  863.  
  864.     string $maxCurves[];
  865.     clear( $maxCurves );
  866.  
  867.  
  868.     string $newAttrs[];
  869.     clear( $newAttrs );
  870.     string $destAttrs[];
  871.     clear( $destAttrs );
  872.     string $destManips[];
  873.     clear( $destManips );
  874.     float $minValues[];
  875.     clear( $minValues );
  876.     float $maxValues[];
  877.     clear( $maxValues );
  878.     float $defaultValues[];
  879.     clear( $defaultValues );
  880.  
  881.     addMarkingAttribute($flowGroup,"surfaceFlowMainManips",1);
  882.     addMarkingAttribute($flowGroup,"surfaceFlowSubManips",1);
  883.     addMarkingAttribute($flowGroup,"surfaceFlowMainRamps",1);
  884.     addMarkingAttribute($flowGroup,"surfaceFlowSubRamps",1);
  885.     addMarkingAttribute($flowGroup,"surfaceFlowMainLofts",1);
  886.     addMarkingAttribute($flowGroup,"surfaceFlowSubLofts",1);
  887.     addMarkingAttribute($flowGroup,"surfaceFlowMainResolutionPlanes",1);
  888.     addMarkingAttribute($flowGroup,"surfaceFlowSubResolutionPlanes",1);
  889.     addMarkingAttribute($flowGroup,"surfaceFlowMainMinCurves",1);
  890.     addMarkingAttribute($flowGroup,"surfaceFlowSubMinCurves",1);
  891.     addMarkingAttribute($flowGroup,"surfaceFlowMainMaxCurves",1);
  892.     addMarkingAttribute($flowGroup,"surfaceFlowSubMaxCurves",1);
  893.     addMarkingAttribute($flowGroup,"surfaceFlowMainEdgeCurves",1);
  894.     addMarkingAttribute($flowGroup,"surfaceFlowSubEdgeCurves",1);
  895.  
  896.     string $locationString = ".uLocation";
  897.     string $minDistString = ".minDistance";
  898.     string $maxDistString = ".maxDistance";
  899.     string $minLocationString = ".minV";
  900.     string $maxLocationString = ".maxV";
  901.  
  902.     string $subExpr = "";
  903.     string $subExprHermite = "";
  904.     string $subExprLinstep = "";
  905.     int $i;
  906.     for( $i = 0; $i < $controlResolution; $i ++ )
  907.     {
  908.         float $location = $minValue + $range * ($i / ($controlResolution - 1.0));
  909.  
  910.         string $manip = createNormalSurfaceManip( $newSurface, $type, $location, 2, $manipResolution );
  911.         setAttr ($manip+".template") 1;
  912.         markObjectWithAttribute($manip,$flowGroup,"surfaceFlowMainManips");
  913.  
  914.         string $ramp = getRampFromNormalSurfaceManip( $manip );
  915.         markObjectWithAttribute($ramp,$flowGroup,"surfaceFlowMainRamps");
  916.  
  917.         string $loft = getLoftFromNormalSurfaceManip( $manip );
  918.         markObjectWithAttribute($loft,$flowGroup,"surfaceFlowMainLofts");
  919.  
  920.         string $resPlane = getResolutionPlaneFromNormalSurfaceManip( $manip );
  921.         markObjectWithAttribute($resPlane,$flowGroup,"surfaceFlowMainResolutionPlanes");
  922.  
  923.         string $edgeCurve = getEdgeCurveFromNormalSurfaceManip( $manip );
  924.         markObjectWithAttribute($edgeCurve,$flowGroup,"surfaceFlowMainEdgeCurves");
  925.  
  926.         string $minCurve = getMinCurveFromNormalSurfaceManip( $manip );
  927.         markObjectWithAttribute($minCurve,$flowGroup,"surfaceFlowMainMinCurves");
  928.  
  929.         string $maxCurve = getMaxCurveFromNormalSurfaceManip( $manip );
  930.         markObjectWithAttribute($maxCurve,$flowGroup,"surfaceFlowMainMaxCurves");
  931.  
  932.         //
  933.         // Add the attributes to the main group to control this manipulator.
  934.         //
  935.         $locationString = "uLocation";
  936.         $minString = "minV";
  937.         $maxString = "maxV";
  938.         float $minSubValue = $surfaceMinV;
  939.         float $maxSubValue = $surfaceMaxV;
  940.         string $minLocValue = min($minSubValue,$maxSubValue); // $surfaceMinU;
  941.         string $maxLocValue = max($minSubValue,$maxSubValue); // $surfaceMaxU;
  942.         if( ( $type == "v" ) || ( $type == "-v" ) )
  943.         {
  944.             $locationString = "vLocation";
  945.             $minString = "minU";
  946.             $maxString = "maxU";
  947.             // $minSubValue = $surfaceMinU;
  948.             // $maxSubValue = $surfaceMaxU;
  949.             // $minLocValue = $surfaceMinV;
  950.             // $maxLocValue = $surfaceMaxV;
  951.  
  952.             //
  953.             // Since the surface that the effect is actually working
  954.             // with the now guaranteed to be parameterized between 0
  955.             // and 1, we do not need to monitor the original surface's
  956.             // parametric range.
  957.             //
  958.             $minSubValue = 0;
  959.             $maxSubValue = 1;
  960.             $minLocValue = 0;
  961.             $maxLocValue = 1;
  962.         }
  963.  
  964.         string $attrName = ($locationString+$i);
  965.         string $destName = $locationString;
  966.         $newAttrs = appendSingleToStringArray( $newAttrs, $attrName );
  967.         $destAttrs = appendSingleToStringArray( $destAttrs, $destName );
  968.         $minValues = appendSingleToFloatArray( $minValues, $minLocValue );
  969.         $maxValues = appendSingleToFloatArray( $maxValues, $maxLocValue );
  970.         $defaultValues = appendSingleToFloatArray( $defaultValues, $location );
  971.         $destManips = appendSingleToStringArray( $destManips, $manip );
  972.  
  973.         $attrName = ($minString+$i);
  974.         $destName = $minString;
  975.         $newAttrs = appendSingleToStringArray( $newAttrs, $attrName );
  976.         $destAttrs = appendSingleToStringArray( $destAttrs, $destName );
  977.         $minValues = appendSingleToFloatArray( $minValues, $minSubValue );
  978.         $maxValues = appendSingleToFloatArray( $maxValues, $maxSubValue );
  979.         $defaultValues = appendSingleToFloatArray( $defaultValues, $minSubValue );
  980.         $destManips = appendSingleToStringArray( $destManips, $manip );
  981.  
  982.         $attrName = ($maxString+$i);
  983.         $destName = $maxString;
  984.         $newAttrs = appendSingleToStringArray( $newAttrs, $attrName );
  985.         $destAttrs = appendSingleToStringArray( $destAttrs, $destName );
  986.         $minValues = appendSingleToFloatArray( $minValues, $minSubValue );
  987.         $maxValues = appendSingleToFloatArray( $maxValues, $maxSubValue );
  988.         $defaultValues = appendSingleToFloatArray( $defaultValues, $maxSubValue );
  989.         $destManips = appendSingleToStringArray( $destManips, $manip );
  990.  
  991.         $attrName = ("minDistance"+$i);
  992.         $destName = "minDistance";
  993.         $newAttrs = appendSingleToStringArray( $newAttrs, $attrName );
  994.         $destAttrs = appendSingleToStringArray( $destAttrs, $destName );
  995.         $minValues = appendSingleToFloatArray( $minValues, 0 );
  996.         $maxValues = appendSingleToFloatArray( $maxValues, 0 );
  997.         $defaultValues = appendSingleToFloatArray( $defaultValues, 1 );
  998.         $destManips = appendSingleToStringArray( $destManips, $manip );
  999.  
  1000.         $attrName = ("maxDistance"+$i);
  1001.         $destName = "maxDistance";
  1002.         $newAttrs = appendSingleToStringArray( $newAttrs, $attrName );
  1003.         $destAttrs = appendSingleToStringArray( $destAttrs, $destName );
  1004.         $minValues = appendSingleToFloatArray( $minValues, 0 );
  1005.         $maxValues = appendSingleToFloatArray( $maxValues, 0 );
  1006.         $defaultValues = appendSingleToFloatArray( $defaultValues, 2 );
  1007.         $destManips = appendSingleToStringArray( $destManips, $manip );
  1008.  
  1009.         //
  1010.         // Add subControl Manips
  1011.         //
  1012.         $locationString = ".uLocation";
  1013.         $minDistString = ".minDistance";
  1014.         $maxDistString = ".maxDistance";
  1015.         $minLocationString = ".minV";
  1016.         $maxLocationString = ".maxV";
  1017.         if( ( $type == "v" ) || ( $type == "-v" ) )
  1018.         {
  1019.             $locationString = ".vLocation";
  1020.             $minLocationString = ".minU";
  1021.             $maxLocationString = ".maxU";
  1022.         }
  1023.         if( $i > 0 )
  1024.         {
  1025.             int $j;
  1026.             for( $j = 0; $j < $subControlResolution; $j ++ )
  1027.             {
  1028.                 float $startLoc = $minSubValue + $range * ( ( $i - 1 ) / ( $controlResolution - 1.0 ) );
  1029.                 float $endLoc = $minSubValue + $range * ( $i / ( $controlResolution - 1.0 ) );
  1030.                 float $subRange = $endLoc - $startLoc;
  1031.                 float $ratioRange = $subRange / ( $subControlResolution + 1.0 );
  1032.                 float $subLocation = $startLoc + ( $j + 1 ) * $ratioRange;
  1033.  
  1034.                 string $subManip = createNormalSurfaceManip( $newSurface, $type, $subLocation, 2, $manipResolution );
  1035.                 setAttr ($subManip+".template") 1;
  1036.                 markObjectWithAttribute($subManip,$flowGroup,"surfaceFlowSubManips");
  1037.  
  1038.                 string $subRamp = getRampFromNormalSurfaceManip( $subManip );
  1039.                 markObjectWithAttribute($subRamp,$flowGroup,"surfaceFlowSubRamps");
  1040.  
  1041.                 string $subLoft = getLoftFromNormalSurfaceManip( $subManip );
  1042.                 markObjectWithAttribute($subLoft,$flowGroup,"surfaceFlowSubLofts");
  1043.  
  1044.                 string $subResPlane = getResolutionPlaneFromNormalSurfaceManip( $subManip );
  1045.                 markObjectWithAttribute($subResPlane,$flowGroup,"surfaceFlowSubResolutionPlanes");
  1046.  
  1047.                 string $subEdgeCurve = getEdgeCurveFromNormalSurfaceManip( $subManip );
  1048.                 markObjectWithAttribute($subEdgeCurve,$flowGroup,"surfaceFlowSubEdgeCurves");
  1049.  
  1050.                 string $subMinCurve = getMinCurveFromNormalSurfaceManip( $subManip );
  1051.                 markObjectWithAttribute($subMinCurve,$flowGroup,"surfaceFlowSubMinCurves");
  1052.  
  1053.                 string $subMaxCurve = getMaxCurveFromNormalSurfaceManip( $subManip );
  1054.                 markObjectWithAttribute($subMaxCurve,$flowGroup,"surfaceFlowSubMaxCurves");
  1055.  
  1056.                 float $ratio = ($j + 1.0)/($subControlResolution + 1.0);
  1057.                 $subExprHermite += ("\t"+$subManip+$locationString+" = hermite( $L["+($i-1)+"], $L["+$i+"], $dL["+($i-1)+"], $dL["+$i+"], "+$ratio+" );\n");
  1058.                 $subExprHermite += ("\t"+$subManip+$minDistString+" = hermite( $MND["+($i-1)+"], $MND["+$i+"], $dMND["+($i-1)+"], $dMND["+$i+"], "+$ratio+" );\n");
  1059.                 $subExprHermite += ("\t"+$subManip+$maxDistString+" = hermite( $MXD["+($i-1)+"], $MXD["+$i+"], $dMXD["+($i-1)+"], $dMXD["+$i+"], "+$ratio+" );\n");
  1060.                 $subExprHermite += ("\t"+$subManip+$minLocationString+" = hermite( $MNL["+($i-1)+"], $MNL["+$i+"], $dMNL["+($i-1)+"], $dMNL["+$i+"], "+$ratio+" );\n");
  1061.                 $subExprHermite += ("\t"+$subManip+$maxLocationString+" = hermite( $MXL["+($i-1)+"], $MXL["+$i+"], $dMXL["+($i-1)+"], $dMXL["+$i+"], "+$ratio+" );\n");
  1062.                 $subExprLinstep += ("\t"+$subManip+$locationString+" = $L["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($L["+$i+"] - $L["+($i-1)+"] );\n");
  1063.                 $subExprLinstep += ("\t"+$subManip+$minDistString+" = $MND["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MND["+$i+"] - $MND["+($i-1)+"] );\n");
  1064.                 $subExprLinstep += ("\t"+$subManip+$maxDistString+" = $MXD["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MXD["+$i+"] - $MXD["+($i-1)+"] );\n");
  1065.                 $subExprLinstep += ("\t"+$subManip+$minLocationString+" = $MNL["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MNL["+$i+"] - $MNL["+($i-1)+"] );\n");
  1066.                 $subExprLinstep += ("\t"+$subManip+$maxLocationString+" = $MXL["+($i-1)+"] + linstep( 0, 1, "+$ratio+" ) * ($MXL["+$i+"] - $MXL["+($i-1)+"] );\n");
  1067.             }
  1068.         }
  1069.     }
  1070.  
  1071.     addAttr -at message -ln "_surfaceFlowObject" $flowGroup;
  1072.     $mainManips = surfaceFlowMainManips( $flowGroup );
  1073.     $subManips = surfaceFlowSubManips( $flowGroup );
  1074.     $mainResPlanes = surfaceFlowMainResolutionPlanes( $flowGroup );
  1075.     $subResPlanes = surfaceFlowSubResolutionPlanes( $flowGroup );
  1076.     $ramps = surfaceFlowRamps( $flowGroup );
  1077.     $lofts = surfaceFlowLofts( $flowGroup );
  1078.     $minCurves = surfaceFlowMinCurves( $flowGroup );
  1079.     $maxCurves = surfaceFlowMaxCurves( $flowGroup );
  1080.     $edgeCurves = surfaceFlowEdgeCurves( $flowGroup );
  1081.  
  1082.     if( $subControlResolution > 0 )
  1083.     {
  1084.         $locationString = ".uLocation";
  1085.         $minDistString = ".minDistance";
  1086.         $maxDistString = ".maxDistance";
  1087.         $minLocationString = ".minV";
  1088.         $maxLocationString = ".maxV";
  1089.         if( ( $type == "v" ) || ( $type == "-v" ) )
  1090.         {
  1091.             $locationString = ".vLocation";
  1092.             $minLocationString = ".minU";
  1093.             $maxLocationString = ".maxU";
  1094.         }
  1095.     
  1096.         $subExpr = "float $L[];\n";
  1097.         $subExpr += "clear( $L );\n";
  1098.         $subExpr += "float $MND[];\n";
  1099.         $subExpr += "clear( $MND );\n";
  1100.         $subExpr += "float $MXD[];\n";
  1101.         $subExpr += "clear( $MXD );\n";
  1102.         $subExpr += "float $MNL[];\n";
  1103.         $subExpr += "clear( $MNL );\n";
  1104.         $subExpr += "float $MXL[];\n";
  1105.         $subExpr += "clear( $MXL );\n";
  1106.         $subExpr += "\n";
  1107.         $subExpr += "float $dL[];\n";
  1108.         $subExpr += "clear( $dL );\n";
  1109.         $subExpr += "float $dMND[];\n";
  1110.         $subExpr += "clear( $dMND );\n";
  1111.         $subExpr += "float $dMXD[];\n";
  1112.         $subExpr += "clear( $dMXD );\n";
  1113.         $subExpr += "float $dMNL[];\n";
  1114.         $subExpr += "clear( $dMNL );\n";
  1115.         $subExpr += "float $dMXL[];\n";
  1116.         $subExpr += "clear( $dMXL );\n";
  1117.         $subExpr += "\n";
  1118.         for( $i = 0; $i < size( $mainManips ); $i ++ )
  1119.         {
  1120.             $subExpr += ("$L["+$i+"] = "+$mainManips[$i]+$locationString+";\n");
  1121.             $subExpr += ("$MND["+$i+"] = "+$mainManips[$i]+$minDistString+";\n");
  1122.             $subExpr += ("$MXD["+$i+"] = "+$mainManips[$i]+$maxDistString+";\n");
  1123.             $subExpr += ("$MNL["+$i+"] = "+$mainManips[$i]+$minLocationString+";\n");
  1124.             $subExpr += ("$MXL["+$i+"] = "+$mainManips[$i]+$maxLocationString+";\n");
  1125.         }
  1126.         $subExpr += "\n";
  1127.  
  1128.         $subExpr += "if( "+$flowGroup+".smoothSubManips == 1 )\n";
  1129.         $subExpr += "{\n";
  1130.  
  1131.         $subExpr += "int $i;\n";
  1132.         $subExpr += "for( $i = 0; $i < size( $L ); $i ++ )\n";
  1133.         $subExpr += "{\n";
  1134.         $subExpr += "\tif( $i == 0 )\n";
  1135.         $subExpr += "\t{\n";
  1136.         $subExpr += "\t\t$dL[$i] = $L[1] - $L[0];\n";
  1137.         $subExpr += "\t\t$dMND[$i] = $MND[1] - $MND[0];\n";
  1138.         $subExpr += "\t\t$dMXD[$i] = $MXD[1] - $MXD[0];\n";
  1139.         $subExpr += "\t\t$dMNL[$i] = $MNL[1] - $MNL[0];\n";
  1140.         $subExpr += "\t\t$dMXL[$i] = $MXL[1] - $MXL[0];\n";
  1141.         $subExpr += "\t}\n";
  1142.         $subExpr += "\telse if( $i == size( $L ) - 1 )\n";
  1143.         $subExpr += "\t{\n";
  1144.         $subExpr += "\t\t$dL[$i] = $L[$i] - $L[$i-1];\n";
  1145.         $subExpr += "\t\t$dMND[$i] = $MND[$i] - $MND[$i-1];\n";
  1146.         $subExpr += "\t\t$dMXD[$i] = $MXD[$i] - $MXD[$i-1];\n";
  1147.         $subExpr += "\t\t$dMNL[$i] = $MNL[$i] - $MNL[$i-1];\n";
  1148.         $subExpr += "\t\t$dMXL[$i] = $MXL[$i] - $MXL[$i-1];\n";
  1149.         $subExpr += "\t}\n";
  1150.         $subExpr += "\telse\n";
  1151.         $subExpr += "\t{\n";
  1152.         $subExpr += "\t\tfloat $diff1 = max(.01,$L[$i] - $L[$i-1]);\n";
  1153.         $subExpr += "\t\tfloat $diff2 = max(.01,$L[$i+1] - $L[$i]);\n";
  1154.         $subExpr += "\t\tfloat $factor = min(2.0, max($diff1/$diff2,$diff2/$diff1));\n";
  1155.         $subExpr += "\t\t$dL[$i] = min( $L[$i] - $L[$i-1], $L[$i+1] - $L[$i] ) * $factor;\n";
  1156.         $subExpr += "\t\t$diff1 = $MND[$i] - $MND[$i-1];\n";
  1157.         $subExpr += "\t\t$diff2 = $MND[$i+1] - $MND[$i];\n";
  1158.         $subExpr += "\t\t$dMND[$i] = min( $MND[$i] - $MND[$i-1], $MND[$i+1] - $MND[$i] ) * $factor;\n";
  1159.         $subExpr += "\t\t$diff1 = $MXD[$i] - $MXD[$i-1];\n";
  1160.         $subExpr += "\t\t$diff2 = $MXD[$i+1] - $MXD[$i];\n";
  1161.         $subExpr += "\t\t$dMXD[$i] = min( $MXD[$i] - $MXD[$i-1], $MXD[$i+1] - $MXD[$i] ) * $factor;\n";
  1162.         $subExpr += "\t\t$diff1 = $MNL[$i] - $MNL[$i-1];\n";
  1163.         $subExpr += "\t\t$diff2 = $MNL[$i+1] - $MNL[$i];\n";
  1164.         $subExpr += "\t\t$dMNL[$i] = min( $MNL[$i] - $MNL[$i-1], $MNL[$i+1] - $MNL[$i] ) * $factor;\n";
  1165.         $subExpr += "\t\t$diff1 = $MXL[$i] - $MXL[$i-1];\n";
  1166.         $subExpr += "\t\t$diff2 = $MXL[$i+1] - $MXL[$i];\n";
  1167.         $subExpr += "\t\t$dMXL[$i] = min( $MXL[$i] - $MXL[$i-1], $MXL[$i+1] - $MXL[$i] ) * $factor;\n";
  1168.         $subExpr += "\t}\n";
  1169.         $subExpr += "}\n";
  1170.         $subExpr += $subExprHermite;
  1171.         $subExpr += "}\n";
  1172.         $subExpr += "else\n";
  1173.         $subExpr += "{\n";
  1174.         $subExpr += $subExprLinstep;
  1175.         $subExpr += "}\n";
  1176.         $subExpr += "\n";
  1177.     }
  1178.  
  1179.     // aliasAttr "displayFlow" ($flowGroup+".visibility");
  1180.  
  1181.     addAttr -at bool -dv 0 -ln "displaySubManips" $flowGroup;
  1182.     setAttr -keyable 1 ($flowGroup+".displaySubManips");
  1183.     for( $i = 0; $i < size($subManips); $i ++ )
  1184.     {
  1185.         connectAttr ($flowGroup+".displaySubManips") ($subManips[$i]+".visibility");
  1186.     }
  1187.  
  1188.     //
  1189.     // The "showTrueManipShape" attribute determins how the
  1190.     // manipulators are drawn.  If it is FALSE, the default,
  1191.     // then the full, smooth manipulator surfaces that the
  1192.     // effect ramps are sampling are shown.  If it is TRUE,
  1193.     // then only the resolution planes are shown.  These are
  1194.     // the polygonal surfaces showing the exact shape that the
  1195.     // effect is working with.
  1196.     //
  1197.     addAttr -at bool -dv 0 -ln "showTrueManipShape" $flowGroup;
  1198.     createNode -name "doNotShowTrueManipShape#" reverse;
  1199.     string $reverseNode = getSelectedObject( 0 );
  1200.     connectAttr ($flowGroup+".showTrueManipShape") ($reverseNode+".inputX");
  1201.     setAttr -keyable 1 ($flowGroup+".showTrueManipShape");
  1202.     for( $i = 0; $i < size($mainResPlanes); $i ++ )
  1203.     {
  1204.         connectAttr ($flowGroup+".showTrueManipShape") ($mainResPlanes[$i]+".visibility");
  1205.     }
  1206.     for( $i = 0; $i < size($subResPlanes); $i ++ )
  1207.     {
  1208.         connectAttr ($flowGroup+".showTrueManipShape") ($subResPlanes[$i]+".visibility");
  1209.     }
  1210.     for( $i = 0; $i < size($lofts); $i ++ )
  1211.     {
  1212.         connectAttr ($reverseNode+".outputX") ($lofts[$i]+".visibility");
  1213.     }
  1214.  
  1215.     addAttr -at bool -dv 0 -ln "smoothSubManips" $flowGroup;
  1216.     setAttr -keyable -1 ($flowGroup+".smoothSubManips");
  1217.  
  1218.     if( $subControlResolution > 0 )
  1219.     {
  1220.         expression -alwaysEvaluate false -string $subExpr -name "SubControlInterpolationExpr#";
  1221.     }
  1222.  
  1223.     select $minCurves;
  1224.     loft -ch 1 -u 1 -c 0 -ar 0 -d 1 -rn 0 -po 0;
  1225.     rename "MinLoft";
  1226.     string $minLoft = getSelectedObject( 0 );
  1227.     addAttr -at bool -dv 0 -ln "displayMinLoft" $flowGroup;
  1228.     setAttr -keyable 1 ($flowGroup+".displayMinLoft");
  1229.     connectAttr ($flowGroup+".displayMinLoft") ($minLoft+".visibility");
  1230.     string $loftShape = getShapeFromObject( $minLoft, 0, 0 );
  1231.     setAttr ($loftShape+".curvePrecision") 3;
  1232.     setAttr ($loftShape+".curvePrecisionShaded") 1;
  1233.     setAttr ($loftShape+".simplifyMode") 0;
  1234.     setAttr ($loftShape+".simplifyU") 1;
  1235.     setAttr ($loftShape+".simplifyV") 1;
  1236.     setAttr ($loftShape+".divisionsU") 0;
  1237.     setAttr ($loftShape+".divisionsV") 0;
  1238.     setAttr -lock 1 ($loftShape+".curvePrecision");
  1239.     setAttr -lock 1 ($loftShape+".curvePrecisionShaded");
  1240.     setAttr -lock 1 ($loftShape+".simplifyMode");
  1241.     setAttr -lock 1 ($loftShape+".simplifyU");
  1242.     setAttr -lock 1 ($loftShape+".simplifyV");
  1243.     setAttr -lock 1 ($loftShape+".divisionsU");
  1244.     setAttr -lock 1 ($loftShape+".divisionsV");
  1245.  
  1246.     select $maxCurves;
  1247.     loft -ch 1 -u 1 -c 0 -ar 0 -d 1 -rn 0 -po 0;
  1248.     rename "MaxLoft";
  1249.     string $maxLoft = getSelectedObject( 0 );
  1250.     addAttr -at bool -dv 0 -ln "displayMaxLoft" $flowGroup;
  1251.     setAttr -keyable 1 ($flowGroup+".displayMaxLoft");
  1252.     connectAttr ($flowGroup+".displayMaxLoft") ($maxLoft+".visibility");
  1253.     $loftShape = getShapeFromObject( $maxLoft, 0, 0 );
  1254.     setAttr ($loftShape+".curvePrecision") 3;
  1255.     setAttr ($loftShape+".curvePrecisionShaded") 1;
  1256.     setAttr ($loftShape+".simplifyMode") 0;
  1257.     setAttr ($loftShape+".simplifyU") 1;
  1258.     setAttr ($loftShape+".simplifyV") 1;
  1259.     setAttr ($loftShape+".divisionsU") 0;
  1260.     setAttr ($loftShape+".divisionsV") 0;
  1261.     setAttr -lock 1 ($loftShape+".curvePrecision");
  1262.     setAttr -lock 1 ($loftShape+".curvePrecisionShaded");
  1263.     setAttr -lock 1 ($loftShape+".simplifyMode");
  1264.     setAttr -lock 1 ($loftShape+".simplifyU");
  1265.     setAttr -lock 1 ($loftShape+".simplifyV");
  1266.     setAttr -lock 1 ($loftShape+".divisionsU");
  1267.     setAttr -lock 1 ($loftShape+".divisionsV");
  1268.  
  1269.     select $edgeCurves;
  1270.     loft -ch 1 -u 1 -c 0 -ar 0 -d 1 -rn 0 -po 0;
  1271.     rename "EdgeLoft";
  1272.     string $edgeLoft = getSelectedObject( 0 );
  1273.     addAttr -at bool -dv 0 -ln "displayEdgeLoft" $flowGroup;
  1274.     setAttr -keyable 1 ($flowGroup+".displayEdgeLoft");
  1275.     connectAttr ($flowGroup+".displayEdgeLoft") ($edgeLoft+".visibility");
  1276.     $loftShape = getShapeFromObject( $edgeLoft, 0, 0 );
  1277.     setAttr ($loftShape+".curvePrecision") 3;
  1278.     setAttr ($loftShape+".curvePrecisionShaded") 1;
  1279.     setAttr ($loftShape+".simplifyMode") 0;
  1280.     setAttr ($loftShape+".simplifyU") 1;
  1281.     setAttr ($loftShape+".simplifyV") 1;
  1282.     setAttr ($loftShape+".divisionsU") 0;
  1283.     setAttr ($loftShape+".divisionsV") 0;
  1284.     setAttr -lock 1 ($loftShape+".curvePrecision");
  1285.     setAttr -lock 1 ($loftShape+".curvePrecisionShaded");
  1286.     setAttr -lock 1 ($loftShape+".simplifyMode");
  1287.     setAttr -lock 1 ($loftShape+".simplifyU");
  1288.     setAttr -lock 1 ($loftShape+".simplifyV");
  1289.     setAttr -lock 1 ($loftShape+".divisionsU");
  1290.     setAttr -lock 1 ($loftShape+".divisionsV");
  1291.  
  1292.     addAttr -ln "emitterRate" -dv $emitterRate $flowGroup;
  1293.     setAttr -keyable 1 ($flowGroup+".emitterRate");
  1294.  
  1295.     // Add randomSpeed and randomRadius before calling
  1296.     // makeParticleFlow, if they are not added into the flow group node.
  1297.     //
  1298.     addAttr -ln randomSpeed -dv 0.0 $flowGroup;
  1299.     setAttr -keyable 1 ($flowGroup+".randomSpeed");
  1300.  
  1301.     addAttr -ln randomRadius -dv 0.0 $flowGroup;
  1302.     setAttr -keyable 1 ($flowGroup+".randomRadius");
  1303.  
  1304.     int $manipAttrCount = 5;
  1305.     int $j;
  1306.     for( $i = 0; $i < $manipAttrCount; $i ++ )
  1307.     {
  1308.         int $useRange = 1;
  1309.         if( ( $i == 3 ) || ( $i == 4 ) )
  1310.         {
  1311.             $useRange = 0;
  1312.         }
  1313.         for( $j = 0; $j < $controlResolution; $j ++ )
  1314.         {
  1315.             int $index = $j * $manipAttrCount + $i;
  1316.             if( $useRange == 1 )
  1317.             {
  1318.                 addAttr -ln $newAttrs[$index] -min $minValues[$index] -max $maxValues[$index]
  1319.                     -dv $defaultValues[$index] $flowGroup;
  1320.             }
  1321.             else
  1322.             {
  1323.                 addAttr -ln $newAttrs[$index] -dv $defaultValues[$index] $flowGroup;
  1324.             }
  1325.             setAttr -keyable 1 ($flowGroup+"."+$newAttrs[$index]);
  1326.             connectAttr ($flowGroup+"."+$newAttrs[$index]) ($destManips[$index]+"."+$destAttrs[$index]);
  1327.         }
  1328.     }
  1329.  
  1330.     addAttr -ln "rampCount" -at long -dv (size($ramps)) $flowGroup;
  1331.     setAttr -lock 1 ($flowGroup+".rampCount");
  1332.     setAttr -keyable 0 ($flowGroup+".rampCount");
  1333.  
  1334.     string $rampCenter[] = getMarkedObjects( $ramps[0], "rampCenter" );
  1335.     connectAttr ($rampCenter[0]+".output3D") ($flowGroup+".selectHandle");
  1336.     setAttr ($flowGroup+".displayHandle") 1;
  1337.     getAttr ($flowGroup+".selectHandle");
  1338.  
  1339.     addAttr -at message -multi -indexMatters false -ln "effectStrengthAttribute" $flowGroup;
  1340.     addAttr -at message -multi -indexMatters false -ln "effectStrengthRamp" $flowGroup;
  1341.     addAttr -at message -multi -indexMatters false -ln "effectStrengthArrayMapper" $flowGroup;
  1342.     addAttr -at message -multi -indexMatters false -ln "manipPositionAttribute" $flowGroup;
  1343.     addAttr -at message -multi -indexMatters false -ln "manipPositionArrayMapper" $flowGroup;
  1344.     addAttr -at message -multi -indexMatters false -ln "goalWeightAttribute" $flowGroup;
  1345.     addAttr -at message -multi -indexMatters false -ln "adjustedAgeNormalizedAttribute" $flowGroup;
  1346.  
  1347.     addAttr -dt "string" -ln "surfaceFlowTag" $flowGroup;
  1348.     string $tagValue = getUniqueSurfaceFlowTag();
  1349.     setAttr -type "string" ($flowGroup+".surfaceFlowTag") $tagValue;
  1350.  
  1351.     select $minLoft $maxLoft $edgeLoft;
  1352.     group;
  1353.     rename "LoftGroup";
  1354.     string $loftGroup = getSelectedObject( 0 );
  1355.  
  1356.     shadingNode -asShader lambert -name "surfaceFlowLoftS";
  1357.     string $shader = getSelectedObject( 0 );
  1358.     setAttr ($shader+".color") -type double3 1 1 0;
  1359.     setAttr ($shader+".transparency") -type double3 .5 .5 .5;
  1360.     string $shadingGroup = `sets -renderable true -noSurfaceShader true -empty -name "surfaceFlowLoftSG"`;
  1361.     connectAttr ($shader+".outColor") ($shadingGroup+".surfaceShader");
  1362.     sets -e -forceElement $shadingGroup $loftGroup;
  1363.  
  1364.     //
  1365.     // Set the display properties for the manipulators' polygonal
  1366.     // representation of the resolution.  The main manips will be
  1367.     // drawn with thick borders, while the subControl manips are
  1368.     // drawn with a thin border.  This allows them to be distiguished
  1369.     // when all of the manips are displayed.
  1370.     //
  1371.     select $mainResPlanes;
  1372.     polyOptions
  1373.         -cm "diffuse"
  1374.         -cs 0
  1375.         -dv 0
  1376.         -dc 0
  1377.         -dt 0
  1378.         -dmb 0
  1379.         -db 1
  1380.         -sb 3.0
  1381.         -dw 0
  1382.         -din 0 0 0 0
  1383.         -duv 0
  1384.         -uvt 0
  1385.         -ae
  1386.         -dg 1
  1387.         -ao;
  1388.  
  1389.     select $subResPlanes;
  1390.     polyOptions
  1391.         -cm "diffuse"
  1392.         -cs 0
  1393.         -dv 0
  1394.         -dc 0
  1395.         -dt 0
  1396.         -dmb 0
  1397.         -db 1
  1398.         -sb 1.0
  1399.         -dw 0
  1400.         -din 0 0 0 0
  1401.         -duv 0
  1402.         -uvt 0
  1403.         -ae
  1404.         -dg 1
  1405.         -ao;
  1406.     //
  1407.     // Set display smoothness for the NURBS part of the manipulators.
  1408.     //
  1409.     select $mainManips;
  1410.     displaySmoothness -du 3 -dv 3 -pointsWire 16 -pointsShaded 4;
  1411.     group;
  1412.     rename "ControlManipsGroup";
  1413.     string $mainManipGroup = getSelectedObject( 0 );
  1414.  
  1415.     select $subManips;
  1416.     displaySmoothness -du 0 -dv 0 -pointsWire 4 -pointsShaded 1;
  1417.     if( $subControlResolution > 0 )
  1418.         group;
  1419.     else
  1420.         group -empty;
  1421.     rename "SubManipsGroup";
  1422.     string $subManipGroup = getSelectedObject( 0 );
  1423.  
  1424.     select $mainManipGroup $subManipGroup;
  1425.     group;
  1426.     rename "ManipsGroup";
  1427.     string $manipGroup = getSelectedObject( 0 );
  1428.  
  1429.     parent $newSurface $flowGroup;
  1430.     parent $manipGroup $flowGroup;
  1431.     parent $loftGroup $flowGroup;
  1432.  
  1433.     addMarkingAttribute($flowGroup,"flowingParticles",1);
  1434.     addMarkingAttribute($flowGroup,"surfaceFlowEmitter",0);
  1435.     addMarkingAttribute($flowGroup,"surfaceFlowGoal",0);
  1436.  
  1437.     string $emitter = surfaceFlowEmitter( $flowGroup );
  1438.     connectAttr ($flowGroup+".emitterRate") ($emitter+".rate");
  1439.     string $goal = surfaceFlowGoal( $flowGroup );
  1440.  
  1441.     return $flowGroup;
  1442. }
  1443.  
  1444. proc string[] makeParticleFlow( string $flow, string $particle, string $minRatioAttr, string $maxRatioAttr, string $newGoalAttribute, float $lifespan )
  1445. {
  1446.     // Get surface flow's control ramps.
  1447.     //
  1448.     string $ramps[] = surfaceFlowRamps( $flow );
  1449.     if( size($ramps) == 0 )
  1450.     {
  1451.         error("The surface flow, \""+$flow+"\", has no controls.");
  1452.     }
  1453.  
  1454.     // Get surface flow emitter.
  1455.     //
  1456.     string $emitter = surfaceFlowEmitter( $flow );
  1457.     if( $emitter == "" )
  1458.     {
  1459.         error("The surface flow, \""+$flow+"\", has no surface emitter.");
  1460.     }
  1461.  
  1462.     // Get surface flow goal object(locator).
  1463.     //
  1464.     string $goalLocator = surfaceFlowGoal( $flow );
  1465.     if( $goalLocator == "" )
  1466.     {
  1467.         error("The surface flow, \""+$flow+"\", has no goal object.");
  1468.     }
  1469.  
  1470.     // Get particleShape from input particle. If not exist, create one.
  1471.     //
  1472.     string $particleShape = "";
  1473.     string $givenPShape[] = `ls -o -dag -s -type particle $particle`;
  1474.     if( size($givenPShape) > 0 )
  1475.     {
  1476.         $particleShape = $givenPShape[0];
  1477.     }
  1478.     else
  1479.     {
  1480.         string $particleObj[] = `particle`;
  1481.         $particleShape = $particleObj[1];
  1482.     }
  1483.  
  1484.     // If bad particleShape, return from hear.
  1485.     //
  1486.     if( $particleShape == "" )
  1487.     {
  1488.         error("There is not valid particle object for "+$flow+".");
  1489.     }
  1490.  
  1491.     //setAttr ($particleShape+".particleRenderType") 7;
  1492.  
  1493.     //
  1494.     // Start making particle flow.
  1495.     //
  1496.  
  1497.     // Connect the emitter with the particle.
  1498.     //
  1499.     connectDynamic -em $emitter $particleShape;
  1500.  
  1501.     // Add attributes into the given particleShape.
  1502.     // Those new attributes are necessary to control the flow effects.
  1503.     //
  1504.     if( !`attributeQuery -node $particleShape -exists parentU` )
  1505.         addAttr -ln parentU -dt doubleArray $particleShape;
  1506.     
  1507.     if( !`attributeQuery -node $particleShape -exists parentU0` )
  1508.         addAttr -ln parentU0 -dt doubleArray $particleShape;
  1509.     
  1510.     if( !`attributeQuery -node $particleShape -exists parentV` )
  1511.         addAttr -ln parentV -dt doubleArray $particleShape;
  1512.  
  1513.     if( !`attributeQuery -node $particleShape -exists parentV0` )
  1514.         addAttr -ln parentV0 -dt doubleArray $particleShape;
  1515.  
  1516.     setAttr ($particleShape+".lifespanMode") 1;
  1517.     setAttr ($particleShape+".lifespan") $lifespan;
  1518.  
  1519.     if( !`attributeQuery -node $particleShape -exists ageNormalized` )
  1520.         addAttr -ln ageNormalized -dt doubleArray $particleShape;
  1521.  
  1522.  
  1523.     // "adjustedAgeNormalized#" is used for multi-flow controls.
  1524.     //
  1525.     string $adjustedAge = getUniqueAttrName( $particleShape, "adjustedAgeNormalized#" );
  1526.     addAttr -ln $adjustedAge -dt doubleArray $particleShape;
  1527.  
  1528.     // Connect adjustedAge stuff(adjustedAgeNormalized attribute only) with he flow.
  1529.     //
  1530.     connectAttr -na ($particleShape+"."+$adjustedAge) ($flow+".adjustedAgeNormalizedAttribute");
  1531.  
  1532.  
  1533.     // Add "randomPosition" for random motion control.
  1534.     //
  1535.     if( !`attributeQuery -node $particleShape -exists randomPosition` )
  1536.         addAttr -ln "randomPosition" -dt vectorArray $particleShape;
  1537.     if( !`attributeQuery -node $particleShape -exists randomPosition0` )
  1538.         addAttr -ln "randomPosition0" -dt vectorArray $particleShape;
  1539.  
  1540.  
  1541.     if( !`attributeQuery -node $particleShape -exists goalOffset` )
  1542.         addAttr -ln goalOffset -dt vectorArray $particleShape;
  1543.  
  1544.     if( !`attributeQuery -node $particleShape -exists goalOffset0` )
  1545.         addAttr -ln goalOffset0 -dt vectorArray $particleShape;
  1546.  
  1547.     // Connect the particle with the goal.
  1548.     //
  1549.     string $oldGoalWeightAttrs[] = `listAttr -multi -string "goalWeight" $particleShape`;
  1550.     goal -w 1 -utr 0 -g $goalLocator $particleShape;
  1551.     string $newGoalWeightAttrs[] = `listAttr -multi -string "goalWeight" $particleShape`;
  1552.     string $goalAttr = "";
  1553.     int $g;
  1554.     for( $g = 0; $g < size($newGoalWeightAttrs); $g ++ )
  1555.     {
  1556.         if( findInStringArray( $newGoalWeightAttrs[$g], $oldGoalWeightAttrs ) == -1 )
  1557.             $goalAttr = $newGoalWeightAttrs[$g];
  1558.     }
  1559.     if( $goalAttr != "" )
  1560.     {
  1561.         setAttr -lock 1 ($particleShape+"."+$goalAttr);
  1562.     }
  1563.  
  1564.     // Connect goal stuff(goalWeight attribute only) with the flow.
  1565.     // This connection is for finding the attribute from the flow group node
  1566.     // and then the attribute can be easily deleted when disable the flow.
  1567.     //
  1568.     connectAttr -na ($particleShape+"."+$goalAttr) ($flow+".goalWeightAttribute");
  1569.  
  1570.     // Connect particle with each ramp?
  1571.     //
  1572.     int $numRamps = size($ramps);
  1573.     string $manipNames[];
  1574.     clear( $manipNames );
  1575.     string $manipArrayMappers[];
  1576.     int $i;
  1577.     for( $i = 0; $i < $numRamps; $i ++ )
  1578.     {
  1579.         $manipNames[$i] = getUniqueAttrName( $particleShape, "manip_#_Position" );
  1580.         addAttr -ln $manipNames[$i] -dt vectorArray $particleShape;
  1581.  
  1582.         $manipArrayMappers = `arrayMapper -target $particleShape -inputU parentU -inputV parentV -destAttr $manipNames[$i] -mapTo $ramps[$i]`;
  1583.  
  1584.         // Conect manip stuff with the flow for easily handling from the flow.
  1585.         //
  1586.         connectAttr -na ($particleShape+"."+$manipNames[$i]) ($flow+".manipPositionAttribute");
  1587.         connectAttr -na ($manipArrayMappers[0]+".message") ($flow+".manipPositionArrayMapper");
  1588.  
  1589.         //
  1590.         // Disconnect the ramp's outColor attribute from the arrayMapper.
  1591.         // This connection is only used for arrayMappers that are a part of
  1592.         // some rendering network.  These arrayMappers and ramps are a part
  1593.         // of the dynamics computation.
  1594.         //
  1595.         disconnectAttr ($ramps[$i]+".outColor") ($manipArrayMappers[0]+".computeNodeColor");
  1596.     }
  1597.  
  1598.     // Create another ramp to drive effectStrength, if the effectStrength
  1599.     // has not exist and not been controlled.
  1600.     //
  1601.     string $EStrengthAttr = getUniqueAttrName($particleShape,"effectStrength#");
  1602.     addAttr -ln $EStrengthAttr -dt doubleArray $particleShape;
  1603.  
  1604.     string $ESRamp = `shadingNode -asTexture ramp`;
  1605.     $ESRamp = `rename $ESRamp "SurfaceFlowStrength#"`;
  1606.     removeMultiInstance -break true ($ESRamp+".colorEntryList[1]");
  1607.     removeMultiInstance -break true ($ESRamp+".colorEntryList[2]");
  1608.     setAttr ($ESRamp+".colorEntryList[0].color") -type double3 1 1 1;
  1609.  
  1610.     string $strengthArrayMapper[] = `arrayMapper -target $particleShape -inputV $adjustedAge -destAttr $EStrengthAttr -mapTo $ESRamp`;
  1611.  
  1612.     // Conect particle effectStrength stuff(attribute, ramp, arrayMapper) with the flow.
  1613.     //
  1614.     connectAttr -na ($particleShape+"."+$EStrengthAttr) ($flow+".effectStrengthAttribute");
  1615.     connectAttr -na ($ESRamp+".message") ($flow+".effectStrengthRamp");
  1616.     connectAttr -na ($strengthArrayMapper[0]+".message") ($flow+".effectStrengthArrayMapper");
  1617.  
  1618.     //
  1619.     // Disconnect the ramp's outColor attribute from the arrayMapper.
  1620.     // This connection is only used for arrayMappers that are a part of
  1621.     // some rendering network.  These arrayMappers and ramps are a part
  1622.     // of the dynamics computation.
  1623.     //
  1624.     disconnectAttr ($ESRamp+".outColor") ($strengthArrayMapper[0]+".computeNodeColor");
  1625.  
  1626.     // creatation expression to initialize.
  1627.     //
  1628.     string $drivingFlows[] = surfaceFlowsDrivingParticle( $particleShape );
  1629.     int $flowCount = size( $drivingFlows );
  1630.  
  1631.     string $cExpression = `dynExpression -q -c -s $particleShape`;
  1632.     if( $flowCount == 0 )
  1633.     {
  1634.         $cExpression += ("// _SF_INIT_TAG\n");
  1635.         $cExpression += ("// NOTE 1: Don't remove the tag, _SF_INIT_TAG.\n");
  1636.         $cExpression += ("// NOTE 2: If adding lines in between _SF_INIT_TAG, they may be deleted when this particle is not driven by any surface flow object.\n");
  1637.         $cExpression += ("//\n");
  1638.         $cExpression += ("float $SFMin, $SFMax;\n\n");
  1639.  
  1640.         $cExpression += ("goalPP = 0;\n");
  1641.         $cExpression += ("goalOffset = "+$manipNames[0]+";\n");
  1642.  
  1643.         // Initialize the randomPosition attribute here.
  1644.         //
  1645.         $cExpression += ("// Initialize randomPosition attribute.\n");
  1646.         $cExpression += ("//\n");
  1647.         $cExpression += ("vector $idVector = particleId;\n");
  1648.         $cExpression += ("randomPosition = dnoise( $idVector * 10.0 ) * 100.0;\n");
  1649.         $cExpression += ("// _SF_INIT_TAG\n");
  1650.     }
  1651.     string $flowTag = surfaceFlowTag( $flow );
  1652.     $cExpression += ("\n\n");
  1653.     $cExpression += ("// "+$flowTag+"\n");
  1654.     $cExpression += ("// NOTE 1: Don't remove the tag, "+$flowTag+".\n");
  1655.     $cExpression += ("// NOTE 2: If adding lines in between "+$flowTag+", they may be deleted when this particle is not driven by the surface flow object, "+$flow+".\n");
  1656.     $cExpression += ("//\n");
  1657.     $cExpression += ("$SFMin = min("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n");
  1658.     $cExpression += ("$SFMax = max("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n");
  1659.     $cExpression += ("if( $SFMin == $SFMax )\n");
  1660.     $cExpression += ("{\n");
  1661.     $cExpression += ("    $SFMin = max($SFMin - 0.01, 0.0);\n");
  1662.     $cExpression += ("    $SFMax = min($SFMax + 0.01, 1.0);\n");
  1663.     $cExpression += ("}\n");
  1664.     $cExpression += ($adjustedAge +" = (ageNormalized - $SFMin)/($SFMax-$SFMin);\n");
  1665.     $cExpression += ("// "+$flowTag+"\n");
  1666.     dynExpression -c -s $cExpression $particleShape;
  1667.  
  1668.     // runtime expression to compute goalOffset.
  1669.     //
  1670.     string $rExpression = `dynExpression -q -r -s $particleShape`;
  1671.     if( $flowCount == 0 )
  1672.     {
  1673.         $rExpression += ("// _SF_INIT_TAG\n");
  1674.         $rExpression += ("// NOTE 1: Don't remove the tag, _SF_INIT_TAG.\n");
  1675.         $rExpression += ("// NOTE 2: If adding lines in between _SF_INIT_TAG, they may be deleted when this particle is not driven by any surface flow object.\n");
  1676.         $rExpression += ("//\n");
  1677.         $rExpression += ("int $i, $SFMinIndex, $SFMaxIndex, $SFNumRamps;\n");
  1678.         $rExpression += ("float $SFIndex, $SFMin, $SFMax;\n");
  1679.         $rExpression += ("vector $SFManipPos[];\n\n");
  1680.  
  1681.         $rExpression += ("goalPP = 0;\n");
  1682.         $rExpression += ("// _SF_INIT_TAG\n");
  1683.     }
  1684.     $rExpression += ("\n\n");
  1685.     $rExpression += ("// "+$flowTag+"\n");
  1686.     $rExpression += ("// NOTE 1: Don't remove the tag, "+$flowTag+".\n");
  1687.     $rExpression += ("// NOTE 2: If adding lines in between "+$flowTag+", they may be deleted when this particle is not driven by the surface flow object, "+$flow+".\n");
  1688.     $rExpression += ("//\n");
  1689.     $rExpression += ("$SFMin = min("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n");
  1690.     $rExpression += ("$SFMax = max("+$flow+"."+$maxRatioAttr+", "+$flow+"."+$minRatioAttr+");\n");
  1691.     $rExpression += ("if( $SFMin == $SFMax )\n");
  1692.     $rExpression += ("{\n");
  1693.     $rExpression += ("    $SFMin = max($SFMin - 0.01, 0.0);\n");
  1694.     $rExpression += ("    $SFMax = min($SFMax + 0.01, 1.0);\n");
  1695.     $rExpression += ("}\n");
  1696.  
  1697.     $rExpression += ("if( (ageNormalized <= $SFMax) && (ageNormalized >= $SFMin) )\n");
  1698.     $rExpression += ("{\n");
  1699.     $rExpression += ("    goalPP = "+$EStrengthAttr+" * "+$newGoalAttribute+";\n");
  1700.     $rExpression += ("    "+$adjustedAge+" = (ageNormalized - $SFMin)/($SFMax-$SFMin);\n\n");
  1701.     $rExpression += ("    clear( $SFManipPos );\n");
  1702.     int $i;
  1703.     for( $i = 0; $i < $numRamps; $i ++ )
  1704.     {
  1705.         $rExpression += ("    $SFManipPos["+$i+"] = "+$manipNames[$i]+";\n");
  1706.     }
  1707.  
  1708.     $rExpression += ("\n");
  1709.     $rExpression += ("    $SFNumRamps = "+$flow+".rampCount;\n");
  1710.     $rExpression += ("    $SFIndex = "+$adjustedAge+" * ($SFNumRamps - 1);\n");
  1711.     $rExpression += ("    $SFMinIndex = $SFIndex;\n\n");
  1712.  
  1713.     // Compute random motion offset and add it into goalOffset.
  1714.     //
  1715.     $rExpression += ("    // Compute random motion offset.\n");
  1716.     $rExpression += ("    //\n");
  1717.     $rExpression += ("    float $randomSpeed = "+$flow+".randomSpeed;\n");
  1718.     $rExpression += ("    float $randomRadius = "+$flow+".randomRadius;\n");
  1719.     $rExpression += ("    vector $randomPos = "+$particleShape+".randomPosition;\n");
  1720.     $rExpression += ("    vector $randomOffset = dnoise( $randomPos + (time * $randomSpeed) ) * $randomRadius;\n\n");
  1721.  
  1722.     $rExpression += ("    if( $SFIndex == $SFMinIndex )\n");
  1723.     $rExpression += ("    {\n");
  1724.     $rExpression += ("        vector $gOffset = $SFManipPos[$SFMinIndex] + $randomOffset;\n");
  1725.     $rExpression += ("        "+$particleShape+".goalOffset = $gOffset;\n");
  1726.     $rExpression += ("    }\n");
  1727.     $rExpression += ("    else\n");
  1728.     $rExpression += ("    {\n");
  1729.     $rExpression += ("        $SFMaxIndex = $SFMinIndex + 1;\n");
  1730.     $rExpression += ("        float $remainder = $SFIndex - $SFMinIndex;\n");
  1731.     $rExpression += ("        vector $gOffset = ($SFManipPos[$SFMinIndex] + ($remainder * ($SFManipPos[$SFMaxIndex] - $SFManipPos[$SFMinIndex])));\n");
  1732.     $rExpression += ("        $gOffset += $randomOffset;\n");
  1733.     $rExpression += ("        "+$particleShape+".goalOffset = $gOffset;\n");
  1734.     $rExpression += ("    }\n");
  1735.     $rExpression += ("}\n");
  1736.     $rExpression += ("// "+$flowTag+"\n");
  1737.  
  1738.     dynExpression -r -s $rExpression $particleShape;
  1739.  
  1740.     string $result[];
  1741.     clear( $result );
  1742.     $result[0] = $particleShape;
  1743.     $result[1] = $goalAttr;
  1744.     $result[2] = $ESRamp;
  1745.     return( $result );
  1746. }
  1747.  
  1748. proc string doFlowAlongSurface(
  1749.     string $name,
  1750.     string $flowObject,
  1751.     string $existingParticleObject,
  1752.     int $createParticleObject,
  1753.     float $lifespan,
  1754.     string $type,
  1755.     int $controlResolution,
  1756.     int $subControlResolution,
  1757.     int $manipResolution,
  1758.     float $goalWeight,
  1759.     float $emitterRate,
  1760.     float $minAgeRatio,
  1761.     float $maxAgeRatio )
  1762. {
  1763.     if( $flowObject == "" )
  1764.     {
  1765.         error("Must supply either a NURBS surface or a surface flow group when using the flowAlongSurface effect.");
  1766.     }
  1767.  
  1768.     if( isObjectIntermediate( $flowObject ) == 1 )
  1769.     {
  1770.         warning("The object, \""+$flowObject+"\", is intermediate.  Skipping");
  1771.         return "";
  1772.     }
  1773.  
  1774.     string $oldNodes[] = `ls`;
  1775.  
  1776.     string $surface = "";
  1777.     string $flowGroup = "";
  1778.     if( isSurfaceFlow( $flowObject ) == 1 )
  1779.     {
  1780.         $flowGroup = $flowObject;
  1781.     }
  1782.     else
  1783.     {
  1784.         string $surfaces[] = `ls -objectsOnly -dag -type nurbsSurface $flowObject`;
  1785.         if( size( $surfaces ) > 0 )
  1786.         {
  1787.             $surface = $surfaces[0];
  1788.         }
  1789.     }
  1790.  
  1791.     if( ( $flowGroup == "" ) && ( $surface == "" ) )
  1792.     {
  1793.         error("Must supply either a NURBS surface or a surface flow group when using the flowAlongSurface effect.");
  1794.     }
  1795.     else if( ($flowGroup == "" ) && ( $surface != "" ) )
  1796.     {
  1797.         $flowGroup = makeSurfaceFlowGroup( $surface, $name, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $minAgeRatio, $maxAgeRatio );
  1798.         addMarkingAttribute( $flowGroup, "nodesToDelete", 1 );
  1799.     }
  1800.  
  1801.     if( $existingParticleObject != "" )
  1802.     {
  1803.         string $shapes[] = getShapesFromObject( $existingParticleObject, 0 );
  1804.         if( size( $shapes ) == 0 )
  1805.             $existingParticleObject = "";
  1806.         else if( size( $shapes ) > 1 )
  1807.         {
  1808.             warning("More than one particle shape found under \""+$existingParticleObject+"\".  Creating a new one.");
  1809.             $existingParticleObject = "";
  1810.         }
  1811.     }
  1812.  
  1813.     if( $existingParticleObject != "" )
  1814.     {
  1815.         // If $existingParticleObject exists,
  1816.         // check if $existingParticleObject belongs to $flowGroup.
  1817.         // If true, return now.
  1818.         //
  1819.         if( isParticleInSurfaceFlow($flowGroup, $existingParticleObject) )
  1820.         {
  1821.             warning("The input particle object, \""+$existingParticleObject+"\", is already controlled by the given surface flow, \""+$flowGroup+"\". No work done.");
  1822.             return $flowGroup;
  1823.         }
  1824.     }
  1825.  
  1826.     if( ( $existingParticleObject != "" ) || ( $createParticleObject == 1 ) )
  1827.     {
  1828.         // string $minRatioAttr = getUniqueAttrName( $flowGroup, "min_#_Ratio" );
  1829.         string $minRatioAttr = getUniqueAttrName( $flowGroup, "minAgeRatio_#" );
  1830.         addAttr -ln $minRatioAttr -dv $minAgeRatio $flowGroup;
  1831.         setAttr -keyable 1 ($flowGroup+"."+$minRatioAttr);
  1832.         // string $maxRatioAttr = getUniqueAttrName( $flowGroup, "max_#_Ratio" );
  1833.         string $maxRatioAttr = getUniqueAttrName( $flowGroup, "maxAgeRatio_#" );
  1834.         addAttr -ln $maxRatioAttr -dv $maxAgeRatio $flowGroup;
  1835.         setAttr -keyable 1 ($flowGroup+"."+$maxRatioAttr);
  1836.  
  1837.         string $newGoalAttribute = "";
  1838.         string $newGoalWeightAttr = getUniqueAttrName( $flowGroup, "goalWeight_#" );
  1839.         addAttr -ln $newGoalWeightAttr -dv $goalWeight $flowGroup;
  1840.         $newGoalAttribute = ($flowGroup+"."+$newGoalWeightAttr);
  1841.         setAttr -keyable 1 $newGoalAttribute;
  1842.  
  1843.         string $flowStuff[] = makeParticleFlow( $flowGroup, $existingParticleObject, $minRatioAttr, $maxRatioAttr, $newGoalAttribute, $lifespan );
  1844.         string $flowParticles = $flowStuff[0];
  1845.         markObjectWithAttribute($flowParticles,$flowGroup,"flowingParticles");
  1846.  
  1847.         if( 0 ) // $flowStuff[1] != "" )
  1848.         {
  1849.             // string $newGoalWeightAttr = getUniqueAttrName( $flowGroup, "goal_#_Weight" );
  1850.             string $newGoalWeightAttr = getUniqueAttrName( $flowGroup, "goalWeight_#" );
  1851.             addAttr -ln $newGoalWeightAttr -dv $goalWeight $flowGroup;
  1852.             setAttr -keyable 1 ($flowGroup+"."+$newGoalWeightAttr);
  1853.             string $goalWeightAttr = ($flowParticles+"."+$flowStuff[1]);
  1854.             connectAttr -f ($flowGroup+"."+$newGoalWeightAttr) $goalWeightAttr;
  1855.         }
  1856.         else
  1857.         {
  1858.             //
  1859.             // If this value is "", then the particle object is already
  1860.             // following the gicen goal object, and no work is needed
  1861.             // here.
  1862.             //
  1863.         }
  1864.     
  1865.         string $seeds[] = `listAttr -multi -string "seed" $flowParticles`;
  1866.         string $flowingParticles[] = surfaceFlowParticles( $flowGroup );
  1867.         if( size($flowingParticles) > 0 )
  1868.             setAttr ($flowParticles+"."+$seeds[size($seeds)-1]) (size($flowingParticles));
  1869.     }
  1870.  
  1871.     string $newNodes[] = `ls`;
  1872.     print("// Performing post-processes for the surface flow.  This may take several minutes.\n");
  1873.     markNewNonDagNodes( $flowGroup, $oldNodes, $newNodes );
  1874.     markNodesNonHistoricallyInteresting( $flowGroup );
  1875.     print("//     ...Done with post-processes.\n");
  1876.  
  1877.     select $flowGroup;
  1878.     return $flowGroup;
  1879. }
  1880.  
  1881. ///////////////////////////////////////////////////////////////////////////////////////
  1882.  
  1883. global proc string[] main_flowAlongSurfaces(
  1884.     string $name,
  1885.     int $createParticle,
  1886.     float $lifespan,
  1887.     int $createParticleForEachFlow,
  1888.     string $type,
  1889.     int $controlResolution,
  1890.     int $subControlResolution,
  1891.     int $manipResolution,
  1892.     float $goalWeight,
  1893.     float $emitterRate,
  1894.     float $minAgeRatio,
  1895.     float $maxAgeRatio )
  1896. {
  1897.     string $results[];
  1898.     clear( $results );
  1899.  
  1900.     if( `licenseCheck -type complete` == 0 )
  1901.     {
  1902.         // warning("You are not licensed to use the Flow Along Along Surface Effect.");
  1903.         error("You are not licensed to use the Flow Along Along Surface Effect.");
  1904.         return $results;
  1905.     }
  1906.  
  1907.     string $flowObjects[] = selectedSurfaceFlowsAndSurfaces();
  1908.     string $particles[] = `ls -sl -objectsOnly -dag -type particle`;
  1909.  
  1910.     if( size( $flowObjects ) == 0 )
  1911.     {
  1912.         // warning("No NURBS surfaces or surface flow objects selected.  Can not continue with flowAlongSurfaces.");
  1913.         error("No NURBS surfaces or surface flow objects selected.  Can not continue with flowAlongSurfaces.");
  1914.         return $results;
  1915.     }
  1916.  
  1917.     if( size( $particles ) == 0 )
  1918.     {
  1919.         int $f;
  1920.         if( $createParticle == 1 )
  1921.         {
  1922.             float $newMin = 0;
  1923.             float $newMax = 0;
  1924.             float $range = ($maxAgeRatio-$minAgeRatio);
  1925.             float $stepSize = $range / size($flowObjects);
  1926.  
  1927.             if( $createParticleForEachFlow == 1 )
  1928.             {
  1929.                 $newMin = $minAgeRatio;
  1930.                 $newMax = $maxAgeRatio;
  1931.             }
  1932.             else
  1933.             {
  1934.                 $newMin = $minAgeRatio;
  1935.                 $newMax = $minAgeRatio + $stepSize;
  1936.             }
  1937.  
  1938.             string $flow = flowAlongSurface( $name, $flowObjects[0],
  1939.                 "", 1, $lifespan, $type, $controlResolution,
  1940.                 $subControlResolution, $manipResolution, $goalWeight,
  1941.                 $emitterRate, $newMin, $newMax );
  1942.             string $particles[] = surfaceFlowParticles( $flow );
  1943.             string $particleObject = $particles[0];
  1944.  
  1945.             if( $flow != "" )
  1946.                 $results = appendSingleToStringArray( $results, $flow );
  1947.  
  1948.             for( $f = 1; $f < size( $flowObjects ); $f ++ )
  1949.             {
  1950.                 int $newParticle = 1;
  1951.                 if( $createParticleForEachFlow == 0 )
  1952.                 {
  1953.                     $newParticle = 0;
  1954.                     $newMin = $minAgeRatio + $stepSize * $f;
  1955.                     $newMax = $minAgeRatio + $stepSize * ($f + 1.0);
  1956.                 }
  1957.                 else
  1958.                 {
  1959.                     $newMin = $minAgeRatio;
  1960.                     $newMax = $maxAgeRatio;
  1961.                 }
  1962.  
  1963.                 if( $newParticle == 0 )
  1964.                 {
  1965.                     $flow = flowAlongSurface( $name, $flowObjects[$f],
  1966.                         $particleObject, 0, $lifespan,$type, $controlResolution,
  1967.                         $subControlResolution, $manipResolution, $goalWeight,
  1968.                         0, $newMin, $newMax );
  1969.                     if( $flow != "" )
  1970.                         $results = appendSingleToStringArray( $results, $flow );
  1971.                 }
  1972.                 else
  1973.                 {
  1974.                     $flow = flowAlongSurface( $name, $flowObjects[$f],
  1975.                         "", 1, $lifespan, $type, $controlResolution,
  1976.                         $subControlResolution, $manipResolution, $goalWeight,
  1977.                         $emitterRate, $newMin, $newMax );
  1978.                     if( $flow != "" )
  1979.                         $results = appendSingleToStringArray( $results, $flow );
  1980.                 }
  1981.             }
  1982.         }
  1983.         else
  1984.         {
  1985.             string $flow = "";
  1986.             for( $f = 0; $f < size( $flowObjects ); $f ++ )
  1987.             {
  1988.                 $flow = flowAlongSurface( $name, $flowObjects[$f],
  1989.                     "", 0, $lifespan, $type, $controlResolution,
  1990.                     $subControlResolution, $manipResolution, $goalWeight,
  1991.                     $emitterRate, $minAgeRatio, $maxAgeRatio );
  1992.                 if( $flow != "" )
  1993.                     $results = appendSingleToStringArray( $results, $flow );
  1994.             }
  1995.         }
  1996.     }
  1997.     else
  1998.     {
  1999.         string $flow = "";
  2000.         int $f;
  2001.         int $p;
  2002.         for( $p = 0; $p < size( $particles ); $p ++ )
  2003.         {
  2004.             for( $f = 0; $f < size( $flowObjects ); $f ++ )
  2005.             {
  2006.                 $flow = flowAlongSurface( $name, $flowObjects[$f],
  2007.                     $particles[$p], 0, $lifespan, $type, $controlResolution,
  2008.                     $subControlResolution, $manipResolution, $goalWeight,
  2009.                     $emitterRate, $minAgeRatio, $maxAgeRatio );
  2010.                 if( $flow != "" )
  2011.                     $results = appendSingleToStringArray( $results, $flow );
  2012.             }
  2013.         }
  2014.     }
  2015.  
  2016.     select $results;
  2017.     return $results;
  2018. }
  2019.  
  2020.  
  2021. global proc string main_flowAlongSurface(
  2022.     string $name,
  2023.     string $flowObject,
  2024.     string $existingParticleObject,
  2025.     int $createParticleObject,
  2026.     float $lifespan,
  2027.     string $type,
  2028.     int $controlResolution,
  2029.     int $subControlResolution,
  2030.     int $manipResolution,
  2031.     float $goalWeight,
  2032.     float $emitterRate,
  2033.     float $minAgeRatio,
  2034.     float $maxAgeRatio )
  2035. {
  2036.     string $result = "";
  2037.     if( `licenseCheck -type complete` == 0 )
  2038.     {
  2039.         // warning("You are not licensed to use the Flow Along Along Surface Effect.");
  2040.         error("You are not licensed to use the Flow Along Along Surface Effect.");
  2041.         return $result;
  2042.     }
  2043.     waitCursor -state on;
  2044.         cycleCheck -e off;
  2045.         if( catch( $result = doFlowAlongSurface( $name, $flowObject, $existingParticleObject, $createParticleObject, $lifespan, $type, $controlResolution, $subControlResolution, $manipResolution, $goalWeight, $emitterRate, $minAgeRatio, $maxAgeRatio ) ) == 1 )
  2046.         {
  2047.             // warning("Some error occurred during the execution of \"flowAlongSurface\" for \""+$flowObject+"\".  Results may be invalid.");
  2048.             waitCursor -state off;
  2049.             error("Some error occurred during the execution of \"flowAlongSurface\" for \""+$flowObject+"\".  Results may be invalid.");
  2050.         }
  2051.     waitCursor -state off;
  2052.     return $result;
  2053. }
  2054.  
  2055. global proc main_deleteSurfaceFlow( string $flow, int $deleteParticle )
  2056. {
  2057.     if( `licenseCheck -type complete` == 0 )
  2058.     {
  2059.         // warning("You are not licensed to use the Flow Along Along Surface Effect.");
  2060.         error("You are not licensed to use the Flow Along Along Surface Effect.");
  2061.         return;
  2062.     }
  2063.  
  2064.     if( isSurfaceFlow( $flow ) == 0 )
  2065.     {
  2066.         error("The object, \""+$flow+"\", is not a surface flow object.");
  2067.     }
  2068.  
  2069.     int $i, $count;
  2070.  
  2071.     if( $deleteParticle )
  2072.     {
  2073.         // Get all particles which are driven by the $flow.
  2074.         // Then delete them if not driving by other surface flow objects.
  2075.         //
  2076.         string $flowingParticles[] = surfaceFlowParticles( $flow );
  2077.         string $drivingFlow[];
  2078.         $count = size($flowingParticles);
  2079.         for( $i = 0; $i < $count; $i++ )
  2080.         {
  2081.             $drivingFlow = surfaceFlowsDrivingParticle($flowingParticles[$i]);
  2082.             if( (size($drivingFlow) == 1) && ($drivingFlow[0] == $flow) )
  2083.             {
  2084.                 string $parent[]=`listRelatives -parent $flowingParticles[$i]`;
  2085.                 delete $parent[0];
  2086.             }
  2087.             else
  2088.             {
  2089.                 removeParticleFromSurfaceFlow( $flow, $flowingParticles[$i] );
  2090.             }
  2091.         }
  2092.     }
  2093.     else
  2094.     {
  2095.         // Have to remove all particle objects from the $flow.
  2096.         // But particles will not be deleted.
  2097.         //
  2098.         removeParticlesFromSurfaceFlow( $flow );
  2099.     }
  2100.  
  2101.  
  2102.     // Delete non-dag nodes which have been created for the $flow.
  2103.     //
  2104.     string $nonDagNodes[] = surfaceFlowNodesToDelete( $flow );
  2105.     $count = size( $nonDagNodes );
  2106.     for( $i = 0; $i < $count; $i++ )
  2107.     {
  2108.         if( `objExists $nonDagNodes[$i]` == 1 )
  2109.         {
  2110.             delete $nonDagNodes[$i];
  2111.         }
  2112.     }
  2113.  
  2114.  
  2115.     // Delete flow.
  2116.     //
  2117.     delete $flow;
  2118. }
  2119.  
  2120. global proc main_deleteSurfaceFlows( int $deleteFlow, int $deleteParticle )
  2121. //
  2122. //  Descriptions:
  2123. //      UI will execute this procedure based on selected surface flow groups.
  2124. //
  2125. //      Logic 1: if $deleteFlow && $deleteParticle, all particles driven by
  2126. //              the selected flows will be deleted. Then delete flows.
  2127. //
  2128. //      Logic 2: if $deleteFlow && !$deleteParticle, break all particles'
  2129. //              connections with selected flows. Then delete flows only.
  2130. //
  2131. //      Logic 3: if !$deleteFlow, ignore $deleteParticle. This procedure
  2132. //              will call removeParticlesFromSurfaceFlow to break all particle
  2133. //              connections with selected flows. Delete nothing.
  2134. //
  2135. //              But if there are also some particle selected, remove each
  2136. //              selected particle from each selected surface flow.
  2137. //
  2138. {
  2139.     if( `licenseCheck -type complete` == 0 )
  2140.     {
  2141.         // warning("You are not licensed to use the Flow Along Along Surface Effect.");
  2142.         error("You are not licensed to use the Flow Along Along Surface Effect.");
  2143.         return;
  2144.     }
  2145.  
  2146.     // Get seleted surface flow groups.
  2147.     //
  2148.     string $flows[] = selectedSurfaceFlows();
  2149.     string $particles[] = `ls -sl -objectsOnly -dag -type particle`;
  2150.  
  2151.     int $i;
  2152.  
  2153.     int $flowCount = size( $flows );
  2154.     int $particleCount = size( $particles );
  2155.  
  2156.     if( $flowCount == 0 )
  2157.     {
  2158.         // warning("There is not any surface flow group selected.");
  2159.         error("There is not any surface flow group selected.");
  2160.         return;
  2161.     }
  2162.  
  2163.     for( $i = 0; $i < $flowCount; $i++ )
  2164.     {
  2165.         if( $deleteFlow != 0 )
  2166.         {
  2167.             deleteSurfaceFlow( $flows[$i], $deleteParticle );
  2168.         }
  2169.         else if( $particleCount == 0 )
  2170.         {
  2171.             removeParticlesFromSurfaceFlow( $flows[$i] );
  2172.         }
  2173.         else
  2174.         {
  2175.             int $j;
  2176.             for( $j = 0; $j < $particleCount; $j++ )
  2177.             {
  2178.                 removeParticleFromSurfaceFlow( $flows[$i], $particles[$j] );
  2179.             }
  2180.         }
  2181.     }
  2182. }
  2183.  
  2184. global proc main_removeParticlesFromSurfaceFlow( string $flow )
  2185. {
  2186.     if( `licenseCheck -type complete` == 0 )
  2187.     {
  2188.         // warning("You are not licensed to use the Flow Along Along Surface Effect.");
  2189.         error("You are not licensed to use the Flow Along Along Surface Effect.");
  2190.         return;
  2191.     }
  2192.  
  2193.     if( isSurfaceFlow( $flow ) == 0 )
  2194.     {
  2195.         error("The object, \""+$flow+"\", is not a surface flow object.");
  2196.     }
  2197.  
  2198.     string $flowParticles[] = surfaceFlowParticles( $flow );
  2199.     int $numParticles = size( $flowParticles );
  2200.     if( $numParticles == 0 )
  2201.         return;
  2202.  
  2203.     int $i;
  2204.     for( $i = 0; $i < $numParticles; $i ++ )
  2205.     {
  2206.         removeParticleFromSurfaceFlow( $flow, $flowParticles[$i] );
  2207.     }
  2208. }
  2209.  
  2210. global proc main_removeParticleFromSurfaceFlow( string $flow, string $particleShape )
  2211. {
  2212.     if( `licenseCheck -type complete` == 0 )
  2213.     {
  2214.         // warning("You are not licensed to use the Flow Along Along Surface Effect.");
  2215.         error("You are not licensed to use the Flow Along Along Surface Effect.");
  2216.         return;
  2217.     }
  2218.  
  2219.     if( isSurfaceFlow( $flow ) == 0 )
  2220.     {
  2221.         error("The object, \""+$flow+"\", is not a surface flow object.");
  2222.     }
  2223.  
  2224.     if( `objExists $particleShape` == 0 )
  2225.     {
  2226.         error("The particleShape, \""+$particleShape+"\", does not exist.");
  2227.     }
  2228.  
  2229.     // Get the shape, in case $particleShape is not a shape.
  2230.     //
  2231.     string $particleShapes[] = `ls -o -dag -s -type particle $particleShape`;
  2232.     if( size($particleShapes) == 0 )
  2233.         return;
  2234.     $particleShape = $particleShapes[0];
  2235.  
  2236.     // Disconnect particleShape with the emitter.
  2237.     //
  2238.     string $emitter = surfaceFlowEmitter( $flow );
  2239.     connectDynamic -d -em $emitter $particleShape;
  2240.  
  2241.  
  2242.     // Remove expression for surface flow.
  2243.     //
  2244.     string $expression, $newExpression;
  2245.     string $tagStr = surfaceFlowTag( $flow );
  2246.     string $searchStr = "\n*// "+$tagStr+".*"+$tagStr+"\n*";
  2247.     string $replaceStr = "\n\n";
  2248.  
  2249.     string $drivingFlows[] = surfaceFlowsDrivingParticle( $particleShape );
  2250.     int $flowCount = size( $drivingFlows );
  2251.     string $searchStrInit = "\n*// _SF_INIT_TAG.*_SF_INIT_TAG\n*";
  2252.  
  2253.     // For creatation expression.
  2254.     //
  2255.     $expression = `dynExpression -q -c -s $particleShape`;
  2256.     $newExpression = substitute( $searchStr, $expression, $replaceStr );
  2257.     if( $flowCount == 1 )
  2258.         $newExpression = substitute( $searchStrInit, $newExpression, $replaceStr );
  2259.     dynExpression -c -s $newExpression $particleShape;
  2260.  
  2261.     // For runtime expression.
  2262.     //
  2263.     $expression = `dynExpression -q -r -s $particleShape`;
  2264.     $newExpression = substitute( $searchStr, $expression, $replaceStr );
  2265.     if( $flowCount == 1 )
  2266.         $newExpression = substitute( $searchStrInit, $newExpression, $replaceStr );
  2267.     dynExpression -r -s $newExpression $particleShape;
  2268.  
  2269.     // Delete randomPosition attribute if $flowCount == 1. The reason is that
  2270.     // the particle object has only one attribute for random motion control.
  2271.     // If $flowCount == 1(the particle has only flow control), we can delete
  2272.     // this attribute.
  2273.     //
  2274.     if( $flowCount == 1 )
  2275.     {
  2276.         if( `attributeQuery -node $particleShape -exists randomPosition` )
  2277.         {
  2278.             deleteAttr -at "randomPosition" $particleShape;
  2279.         }
  2280.         if( `attributeQuery -node $particleShape -exists randomPosition0` )
  2281.         {
  2282.             deleteAttr -at "randomPosition0" $particleShape;
  2283.         }
  2284.     }
  2285.  
  2286.     //
  2287.     // Start breaking connections and deleting attributes and some nodes.
  2288.     //
  2289.     int $i, $count;
  2290.  
  2291.     // Remove effect strength stuff.
  2292.     //
  2293.     string $strengthConnections[] = surfaceFlowEffectAttrConnections( $flow, $particleShape );
  2294.     string $strengthObjects[] = surfaceFlowEffectStrengthObjects( $flow, $particleShape );
  2295.  
  2296.     // We need to break connections:
  2297.     // particleShape.effectStrength# <-> flow.effectStrengthAttribute
  2298.     // strengthRamp.message <-> flow.effectStrengthRamp
  2299.     // strengthArrayMapper.message <-> flow.effectStrengthArrayMapper
  2300.     //
  2301.     // Then delete strengthRamp and strengthArrayMapper.
  2302.     // Then delete effectStrength attribute from $particleShape.
  2303.     //
  2304.     $count = size($strengthConnections) - 1;
  2305.     for( $i = 1; $i < $count; $i = $i + 2 )
  2306.     {
  2307.         disconnectAttr ($strengthConnections[$i]) ($strengthConnections[$i+1]);
  2308.     }
  2309.     deleteAttr -at $strengthConnections[0] $particleShape;
  2310.  
  2311.     delete $strengthObjects;
  2312.  
  2313.  
  2314.     // Remove manipPosition stuff.
  2315.     //
  2316.     string $manipStuff[] = surfaceFlowManipPositionAttributes( $flow, $particleShape );
  2317.  
  2318.     // We need to break connections between:
  2319.     // particleShape.manip_#_Position <-> flow.manipPositionAttribute
  2320.     // manipPositionArrayMapper.message <-> flow.manipPositionArrayMapper
  2321.     //
  2322.     // Then delete manipPositionArrayMapper, and maniPositionRamp????.
  2323.     // Then delete manip_#_Position attributes from $particleShape.
  2324.     // Then delete arrayMappers.
  2325.     //
  2326.     int $manipAttrCount = $manipStuff[0];
  2327.     int $startCount = $manipAttrCount + 1;
  2328.     $count = size($manipStuff) - 1;
  2329.     for( $i = $startCount; $i < $count; $i = $i + 2 )
  2330.     {
  2331.         disconnectAttr ($manipStuff[$i]) ($manipStuff[$i+1]);
  2332.     }
  2333.  
  2334.     for( $i = 1; $i <= $manipAttrCount; $i++ )
  2335.     {
  2336.         deleteAttr -at $manipStuff[$i] $particleShape;
  2337.     }
  2338.  
  2339.     string $manipArrayMappers[] = surfaceFlowManipArrayMappers( $flow, $particleShape );
  2340.     delete $manipArrayMappers;
  2341.  
  2342.  
  2343.     // Remove adjustedAge stuff.
  2344.     //
  2345.     string $adjustedAgeStuff[] = surfaceFlowAdjustedAgeNormalizedAttribute( $flow, $particleShape );
  2346.  
  2347.     // We need to break connection between:
  2348.     // particleShape.adjustedAgeNormalized <-> flow.adjustedAgeNormalizedAttribute
  2349.     //
  2350.     // Then delete adjustedAgeNormalized attribute from the $particleShape.
  2351.     //
  2352.     $count = size($adjustedAgeStuff) - 1;
  2353.     for( $i = 1; $i < $count; $i = $i + 2 )
  2354.     {
  2355.         disconnectAttr ($adjustedAgeStuff[$i]) ($adjustedAgeStuff[$i+1]);
  2356.     }
  2357.     deleteAttr -at $adjustedAgeStuff[0] $particleShape;
  2358.  
  2359.  
  2360.     // Remove goal stuff.
  2361.     //
  2362.     string $goalStuff[] = surfaceFlowGoalWeightAttribute( $flow, $particleShape );
  2363.  
  2364.     // We need to break connections between:
  2365.     // particleShape.goalWeight# <-> flow.goalWeightAttribute
  2366.     // and also connections between goalObject and particleShape.
  2367.     //
  2368.     // Then delete goalWeight# attribute from $particleShape.
  2369.     //
  2370.     $count = size($goalStuff) - 1;
  2371.     for( $i = 1; $i < $count; $i = $i + 2 )
  2372.     {
  2373.         disconnectAttr ($goalStuff[$i]) ($goalStuff[$i+1]);
  2374.     }
  2375.     setAttr -lock 0 ($particleShape+".goalWeight["+$goalStuff[0]+"]");
  2376.     removeMultiInstance -break true ($particleShape+".goalWeight["+$goalStuff[0]+"]");
  2377.     removeMultiInstance -break true ($particleShape+".goalActive["+$goalStuff[0]+"]");
  2378.     removeMultiInstance -break true ($particleShape+".goalGeometry["+$goalStuff[0]+"]");
  2379.  
  2380.  
  2381.     // Break connections with the flow.flowingParticles.
  2382.     //
  2383.     string $flowingParticles[] = surfaceFlowParticles( $flow );
  2384.     int $index = findInStringArray( $particleShape, $flowingParticles );
  2385.     string $connections[] = `listConnections -source true -destination false -connections 1 -plugs 1 -shapes 1 ($flow+".flowingParticles")`;
  2386.  
  2387.     disconnectAttr $connections[$index*2+1] $connections[$index*2];
  2388.  
  2389.     cleanupSurfaceFlowAttributes( $flow );
  2390. }
  2391.  
  2392. //////////////////////////////////////////////////////////////////////////////////
  2393.  
  2394. global proc int main_isSurfaceFlow( string $object )
  2395. {
  2396.     if( `objExists $object` == 0 )
  2397.     {
  2398.         return 0;
  2399.     }
  2400.  
  2401.     if( `attributeQuery -node $object -exists "_surfaceFlowObject"` == 1 )
  2402.         return 1;
  2403.     else
  2404.         return 0;
  2405. }
  2406.  
  2407. global proc string[] main_selectedSurfaceFlows()
  2408. {
  2409.     string $result[];
  2410.     clear( $result );
  2411.  
  2412.     string $selection[] = `ls -objectsOnly -sl`;
  2413.     int $i;
  2414.     for( $i = 0; $i < size( $selection ); $i ++ )
  2415.     {
  2416.         if( isSurfaceFlow( $selection[$i] ) == 1 )
  2417.         {
  2418.             if( isObjectIntermediate( $selection[$i] ) == 0 )
  2419.             {
  2420.                 $result = appendSingleToStringArray( $result, $selection[$i] );
  2421.             }
  2422.         }
  2423.     }
  2424.  
  2425.     return $result;
  2426. }
  2427.  
  2428. global proc string[] main_selectedSurfaceFlowsAndSurfaces()
  2429. {
  2430.     string $result[];
  2431.     clear( $result );
  2432.  
  2433.     string $selection[] = `ls -objectsOnly -sl`;
  2434.     int $i;
  2435.     for( $i = 0; $i < size( $selection ); $i ++ )
  2436.     {
  2437.         if( isSurfaceFlow( $selection[$i] ) == 1 )
  2438.         {
  2439.             if( isObjectIntermediate( $selection[$i] ) == 0 )
  2440.             {
  2441.                 $result = appendSingleToStringArray( $result, $selection[$i] );
  2442.             }
  2443.         }
  2444.         else
  2445.         {
  2446.             string $surfaces[] = `ls -objectsOnly -dag -type nurbsSurface $selection[$i]`;
  2447.             int $j;
  2448.             for( $j = 0; $j < size($surfaces); $j ++ )
  2449.             {
  2450.                 if( isObjectIntermediate( $surfaces[$j] ) == 0 )
  2451.                     $result = appendSingleToStringArray( $result, $surfaces[$j] );
  2452.             }
  2453.         }
  2454.     }
  2455.  
  2456.     return $result;
  2457. }
  2458.  
  2459. ///////////////////////////////////////////////////////////////////////////////////
  2460.  
  2461. global proc int main_isParticleInSurfaceFlow( string $object, string $particle )
  2462. {
  2463.     // $object is a flow.
  2464.     if( (`objExists $object` == 0) || (`objExists $particle` == 0) )
  2465.     {
  2466.         return 0;
  2467.     }
  2468.  
  2469.     // Get particleShape if $particle is not a particleShape.
  2470.     //
  2471.     string $givenShapes[] = `ls -o -dag -s -typ particle $particle`;
  2472.     string $givenShape = $givenShapes[0];
  2473.     string $flowParticles[] = surfaceFlowParticles( $object );
  2474.     if( findInStringArray( $givenShape, $flowParticles) != -1 )
  2475.         return 1;
  2476.  
  2477.     return 0;
  2478. }
  2479.  
  2480. global proc string[] main_surfaceFlowParticles( string $object )
  2481. {
  2482.     string $result[];
  2483.     clear( $result );
  2484.  
  2485.     if( isSurfaceFlow( $object ) == 0 )
  2486.     {
  2487.         error("The object, \""+$object+"\", is not a surface flow object.");
  2488.     }
  2489.  
  2490.     $result = getMarkedObjects( $object, "flowingParticles" );
  2491.     return $result;
  2492. }
  2493.  
  2494. global proc string[] main_surfaceFlowsDrivingParticle( string $particle )
  2495. {
  2496.     string $result[];
  2497.     clear( $result );
  2498.  
  2499.     string $particleShapes[] = `ls -o -dag -s -typ particle $particle`;
  2500.     if( size($particleShapes) == 0 )
  2501.         return $result;
  2502.     string $particleShape = $particleShapes[0];
  2503.  
  2504.     string $allNodes[] = `ls`;
  2505.  
  2506.  
  2507.     int $i;
  2508.     for( $i = 0; $i < size( $allNodes ); $i ++ )
  2509.     {
  2510.         if( isSurfaceFlow( $allNodes[$i] ) == 1 )
  2511.         {
  2512.             if( isParticleInSurfaceFlow( $allNodes[$i], $particleShape ) )
  2513.                 $result = appendSingleToStringArray( $result, $allNodes[$i] );
  2514.         }
  2515.     }
  2516.  
  2517.     return $result;
  2518. }
  2519.  
  2520. //////////////////////////////////////////////////////////////////////////
  2521.  
  2522. global proc string main_surfaceFlowReferenceSurface( string $object )
  2523. {
  2524.     if( isSurfaceFlow( $object ) == 0 )
  2525.     {
  2526.         error("The object, \""+$object+"\", is not a surface flow object.");
  2527.     }
  2528.  
  2529.     // string $surface[] = `listConnections -source true -destination false ($object+".referenceFlowSurface")`;
  2530.     string $surface[] = getMarkedObjects( $object, "referenceFlowSurface" );
  2531.     if( size($surface) == 0 )
  2532.     {
  2533.         return "";
  2534.     }
  2535.  
  2536.     return $surface[0];
  2537. }
  2538.  
  2539. global proc string main_surfaceFlowActualSurface( string $object )
  2540. {
  2541.     if( isSurfaceFlow( $object ) == 0 )
  2542.     {
  2543.         error("The object, \""+$object+"\", is not a surface flow object.");
  2544.     }
  2545.  
  2546.     // string $surface[] = `listConnections -source true -destination false ($object+".actualFlowSurface")`;
  2547.     string $surface[] = getMarkedObjects( $object, "actualFlowSurface" );
  2548.     if( size($surface) == 0 )
  2549.     {
  2550.         return "";
  2551.     }
  2552.  
  2553.     return $surface[0];
  2554. }
  2555.  
  2556. global proc string main_surfaceFlowEmitter( string $object )
  2557. {
  2558.     if( isSurfaceFlow( $object ) == 0 )
  2559.     {
  2560.         error("The object, \""+$object+"\", is not a surface flow object.");
  2561.     }
  2562.  
  2563.     string $result[] = getMarkedObjects( $object, "surfaceFlowEmitter" );
  2564.     if( size( $result ) == 0 )
  2565.     {
  2566.         string $lofts[] = surfaceFlowLofts( $object );
  2567.         if( size($lofts) == 0 )
  2568.         {
  2569.             return "";
  2570.         }
  2571.         else
  2572.         {
  2573.             emitter -type surface -mxd 0 -mnd 0 -r 10 -spd 0 -nsp 1 -tsp 0 $lofts[0];
  2574.             string $emitter = getSelectedObject( 0 );
  2575.             setAttr ($emitter+".needParentUV") 1;
  2576.             markObjectWithAttribute( $emitter, $object, "surfaceFlowEmitter" );
  2577.             return $emitter;
  2578.         }
  2579.     }
  2580.     else
  2581.     {
  2582.         return $result[0];
  2583.     }
  2584. }
  2585.  
  2586. global proc string main_surfaceFlowGoal( string $object )
  2587. {
  2588.     if( isSurfaceFlow( $object ) == 0 )
  2589.     {
  2590.         error("The object, \""+$object+"\", is not a surface flow object.");
  2591.     }
  2592.  
  2593.     string $result[] = getMarkedObjects( $object, "surfaceFlowGoal" );
  2594.     if( size( $result ) == 0 )
  2595.     {
  2596.         spaceLocator;
  2597.         string $locator = getSelectedObject( 0 );
  2598.         lockTransformations( $locator );
  2599.         parent $locator $object;
  2600.         setAttr ($locator+".inheritsTransform") 0;
  2601.         markObjectWithAttribute( $locator, $object, "surfaceFlowGoal" );
  2602.         hide $locator;
  2603.         setAttr ($locator+".template") 1;
  2604.         return $locator;
  2605.     }
  2606.     else
  2607.     {
  2608.         return $result[0];
  2609.     }
  2610. }
  2611.  
  2612. global proc string[] main_surfaceFlowManips( string $object )
  2613. {
  2614.     string $result[];
  2615.     clear( $result );
  2616.  
  2617.     if( isSurfaceFlow( $object ) == 0 )
  2618.     {
  2619.         error("The object, \""+$object+"\", is not a surface flow object.");
  2620.     }
  2621.  
  2622.     string $mainManips[] = surfaceFlowMainManips( $object );
  2623.     string $subManips[] = surfaceFlowSubManips( $object );
  2624.     int $subsPerMain = size($subManips) / (size($mainManips)-1);
  2625.  
  2626.     $result[0] = $mainManips[0];
  2627.     int $currentSub = 0;
  2628.     int $i;
  2629.     for( $i = 1; $i < size($mainManips); $i ++ )
  2630.     {
  2631.         int $j;
  2632.         for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ )
  2633.         {
  2634.             $result = appendSingleToStringArray( $result, $subManips[$j] );
  2635.         }
  2636.         $currentSub += $subsPerMain;
  2637.         $result = appendSingleToStringArray( $result, $mainManips[$i] );
  2638.     }
  2639.  
  2640.     return $result;
  2641. }
  2642.  
  2643. global proc string[] main_surfaceFlowRamps( string $object )
  2644. {
  2645.     string $result[];
  2646.     clear( $result );
  2647.  
  2648.     if( isSurfaceFlow( $object ) == 0 )
  2649.     {
  2650.         error("The object, \""+$object+"\", is not a surface flow object.");
  2651.     }
  2652.  
  2653.     string $mainRamps[] = surfaceFlowMainRamps( $object );
  2654.     string $subRamps[] = surfaceFlowSubRamps( $object );
  2655.     int $subsPerMain = size($subRamps) / (size($mainRamps)-1);
  2656.  
  2657.     $result[0] = $mainRamps[0];
  2658.     int $currentSub = 0;
  2659.     int $i;
  2660.     for( $i = 1; $i < size($mainRamps); $i ++ )
  2661.     {
  2662.         int $j;
  2663.         for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ )
  2664.         {
  2665.             $result = appendSingleToStringArray( $result, $subRamps[$j] );
  2666.         }
  2667.         $currentSub += $subsPerMain;
  2668.         $result = appendSingleToStringArray( $result, $mainRamps[$i] );
  2669.     }
  2670.  
  2671.     return $result;
  2672. }
  2673.  
  2674. global proc string[] main_surfaceFlowLofts( string $object )
  2675. {
  2676.     string $result[];
  2677.     clear( $result );
  2678.  
  2679.     if( isSurfaceFlow( $object ) == 0 )
  2680.     {
  2681.         error("The object, \""+$object+"\", is not a surface flow object.");
  2682.     }
  2683.  
  2684.     string $mainLofts[] = surfaceFlowMainLofts( $object );
  2685.     string $subLofts[] = surfaceFlowSubLofts( $object );
  2686.     int $subsPerMain = size($subLofts) / (size($mainLofts)-1);
  2687.  
  2688.     $result[0] = $mainLofts[0];
  2689.     int $currentSub = 0;
  2690.     int $i;
  2691.     for( $i = 1; $i < size($mainLofts); $i ++ )
  2692.     {
  2693.         int $j;
  2694.         for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ )
  2695.         {
  2696.             $result = appendSingleToStringArray( $result, $subLofts[$j] );
  2697.         }
  2698.         $currentSub += $subsPerMain;
  2699.         $result = appendSingleToStringArray( $result, $mainLofts[$i] );
  2700.     }
  2701.  
  2702.     return $result;
  2703. }
  2704.  
  2705. global proc string[] main_surfaceFlowResolutionPlanes( string $object )
  2706. {
  2707.     string $result[];
  2708.     clear( $result );
  2709.  
  2710.     if( isSurfaceFlow( $object ) == 0 )
  2711.     {
  2712.         error("The object, \""+$object+"\", is not a surface flow object.");
  2713.     }
  2714.  
  2715.     string $mainResolutionPlanes[] = surfaceFlowMainResolutionPlanes( $object );
  2716.     string $subResolutionPlanes[] = surfaceFlowSubResolutionPlanes( $object );
  2717.     int $subsPerMain = size($subResolutionPlanes) / (size($mainResolutionPlanes)-1);
  2718.  
  2719.     $result[0] = $mainResolutionPlanes[0];
  2720.     int $currentSub = 0;
  2721.     int $i;
  2722.     for( $i = 1; $i < size($mainResolutionPlanes); $i ++ )
  2723.     {
  2724.         int $j;
  2725.         for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ )
  2726.         {
  2727.             $result = appendSingleToStringArray( $result, $subResolutionPlanes[$j] );
  2728.         }
  2729.         $currentSub += $subsPerMain;
  2730.         $result = appendSingleToStringArray( $result, $mainResolutionPlanes[$i] );
  2731.     }
  2732.  
  2733.     return $result;
  2734. }
  2735.  
  2736. global proc string[] main_surfaceFlowEdgeCurves( string $object )
  2737. {
  2738.     string $result[];
  2739.     clear( $result );
  2740.  
  2741.     if( isSurfaceFlow( $object ) == 0 )
  2742.     {
  2743.         error("The object, \""+$object+"\", is not a surface flow object.");
  2744.     }
  2745.  
  2746.     string $mainEdgeCurves[] = surfaceFlowMainEdgeCurves( $object );
  2747.     string $subEdgeCurves[] = surfaceFlowSubEdgeCurves( $object );
  2748.     int $subsPerMain = size($subEdgeCurves) / (size($mainEdgeCurves)-1);
  2749.  
  2750.     $result[0] = $mainEdgeCurves[0];
  2751.     int $currentSub = 0;
  2752.     int $i;
  2753.     for( $i = 1; $i < size($mainEdgeCurves); $i ++ )
  2754.     {
  2755.         int $j;
  2756.         for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ )
  2757.         {
  2758.             $result = appendSingleToStringArray( $result, $subEdgeCurves[$j] );
  2759.         }
  2760.         $currentSub += $subsPerMain;
  2761.         $result = appendSingleToStringArray( $result, $mainEdgeCurves[$i] );
  2762.     }
  2763.  
  2764.     return $result;
  2765. }
  2766.  
  2767. global proc string[] main_surfaceFlowMinCurves( string $object )
  2768. {
  2769.     string $result[];
  2770.     clear( $result );
  2771.  
  2772.     if( isSurfaceFlow( $object ) == 0 )
  2773.     {
  2774.         error("The object, \""+$object+"\", is not a surface flow object.");
  2775.     }
  2776.  
  2777.     string $mainMinCurves[] = surfaceFlowMainMinCurves( $object );
  2778.     string $subMinCurves[] = surfaceFlowSubMinCurves( $object );
  2779.     int $subsPerMain = size($subMinCurves) / (size($mainMinCurves)-1);
  2780.  
  2781.     $result[0] = $mainMinCurves[0];
  2782.     int $currentSub = 0;
  2783.     int $i;
  2784.     for( $i = 1; $i < size($mainMinCurves); $i ++ )
  2785.     {
  2786.         int $j;
  2787.         for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ )
  2788.         {
  2789.             $result = appendSingleToStringArray( $result, $subMinCurves[$j] );
  2790.         }
  2791.         $currentSub += $subsPerMain;
  2792.         $result = appendSingleToStringArray( $result, $mainMinCurves[$i] );
  2793.     }
  2794.  
  2795.     return $result;
  2796. }
  2797.  
  2798. global proc string[] main_surfaceFlowMaxCurves( string $object )
  2799. {
  2800.     string $result[];
  2801.     clear( $result );
  2802.  
  2803.     if( isSurfaceFlow( $object ) == 0 )
  2804.     {
  2805.         error("The object, \""+$object+"\", is not a surface flow object.");
  2806.     }
  2807.  
  2808.     string $mainMaxCurves[] = surfaceFlowMainMaxCurves( $object );
  2809.     string $subMaxCurves[] = surfaceFlowSubMaxCurves( $object );
  2810.     int $subsPerMain = size($subMaxCurves) / (size($mainMaxCurves)-1);
  2811.  
  2812.     $result[0] = $mainMaxCurves[0];
  2813.     int $currentSub = 0;
  2814.     int $i;
  2815.     for( $i = 1; $i < size($mainMaxCurves); $i ++ )
  2816.     {
  2817.         int $j;
  2818.         for( $j = $currentSub; $j < ($currentSub + $subsPerMain); $j ++ )
  2819.         {
  2820.             $result = appendSingleToStringArray( $result, $subMaxCurves[$j] );
  2821.         }
  2822.         $currentSub += $subsPerMain;
  2823.         $result = appendSingleToStringArray( $result, $mainMaxCurves[$i] );
  2824.     }
  2825.  
  2826.     return $result;
  2827. }
  2828.  
  2829.